1

I have a class

data classOuter (
    val str: String = "fOo"
    ...
    val innerClassInstance: InnerClass= InnerClass(),
) {

  ...
  inner class InnerClass {
     fun foo () {     
         return str.toLowerCase()
     }
  }
}

But I get an error:

Constructor of inner class InnerClass can be called only with receiver of containing class

Is there way to avoid it ?

8
  • 1
    Do you understand what the error is telling you? Why do you think this should work in the first place? Commented Oct 25, 2023 at 8:54
  • 1
    Usually, when a class has a reference to a instance of an inner class defined within, it would be an instance bound to itself. It therefore would not make sense to try to pass it an instance of the inner class to its constructor. Commented Oct 25, 2023 at 9:01
  • Are you really looking for an inner class (which holds a reference to an instance of the enclosing class) or just a nested class? Commented Oct 25, 2023 at 9:13
  • I need acces to str from inner class so it should be inner Commented Oct 25, 2023 at 9:14
  • 1
    You should first clarify what you want val innerClassInstance: InnerClass = InnerClass() to mean. As it is, that does not make sense. What instance of Outer do you want to create an InnerClass out of? And whatever your answer is, ask yourself where that instance of Outer comes from. Commented Oct 25, 2023 at 9:19

2 Answers 2

2

There is chicken and egg problem. Inner class object refers parent class object, which is not yet constructed at this point (at the point of passing parameters to the constructor of parent class).

You may employ lazy initialisation of nested class object, so it would be initialised at the time parent class object already exists. Like:

data class classOuter (
    val str: String = "foo"
) {
  val innerClassInstance: InnerClass by lazy { this.InnerClass() }

  inner class InnerClass {
     fun foo () : String {     
         return str.toLowerCase()
     }
  }
}

fun main() {
    println(classOuter("bar").innerClassInstance.foo())
}
Sign up to request clarification or add additional context in comments.

Comments

0

As per docs Inner classes carry a reference to an object of the outer class, so you need at first initiate the Outer class. As you are trying to pass InnerClass to the constructor of the OuterClass it will cause java.lang.StackOverflowError in the end.

If you remove InnerClass out of constructor it will work:

fun main() {
    val innerClass = OuterClass().InnerClass()
    val outerClass = OuterClass()
    innerClass.foo()
    println(outerClass.name)
}

class OuterClass {

    val name: String = "Foo"

    inner class InnerClass {

        fun foo() {
            println("Nested")
            println(name)
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.