25

Consider the following code:

object SomeObjectA {
    object SomeObjectB {
        val a = "test"
    }
}

val X = SomeObjectA
typealias Y = SomeObjectA

SomeObjectA.SomeObjectB // works
X.SomeObjectB // error
Y.SomeObjectB // error

I can't use val or typealias, which reference the outer object, to refer to a nested object within that outer object. Why?

2
  • Similar issue: youtrack.jetbrains.com/issue/KT-12632 Commented Jun 9, 2017 at 16:12
  • Just encountered same thing to the Y.SomeObjectB, reported as KT-24902, since other issues are similar, but not really the same. Commented Jun 13, 2018 at 11:49

2 Answers 2

7
+100

the compiler error is comes from java, and the kotlin objects convert to java classes as below:

public final class SomeObjectA {
    private SomeObjectA() {/**/}

    public static final SomeObjectA INSTANCE = new SomeObjectA();

    public static final class SomeObjectB {
        private SomeObjectB() {/**/}

        public static final SomeObjectB INSTANCE = new SomeObjectB();
    }
}

SomeObjectA.SomeObjectB is compiled to java code as below:

SomeObjectA.SomeObjectB.INSTANCE;

SomeObjectA is compiled to java code as below:

SomeObjectA.INSTANCE

we know kotlin is base on java, and java don't allow access the nested classes via instance reference, if you do the compiler will reports an error:"Error: java: unexpected type required: class,package found: variable", for example:

SomeObjectA a = SomeObjectA.INSTANCE;
SomeObjectB b = a.SomeObjectB.INSTANCE;// error 
             // ^--- compiler don't know where to go? package&class or variable?   

the code below, kotlin compiler will transforms the java compiler error as: "Error: Kotlin: Nested object 'SomeObjectB' accessed via instance reference".

val a = SomeObjectA;
val b = a.SomeObjectB;
//        ^--- Error

Type aliases do not introduce new types. They are equivalent to the corresponding underlying types.

so the two statements below are equality:

 val a = SomeObjectA;
 typealias a2 = SomeObjectA;

avoiding to the use of typealias causing unnecessary compiler error, kotlin doesn't include all nested classes in typealias.

Sign up to request clarification or add additional context in comments.

Comments

6

What you described happens because SomeObjectA in your example is simultaneously a name of an object and the name of its class.

So to access SomeObjectB, you need to use the <classname>.<classname> syntax. That is why X.SomeObjectB doesn't compile (<object>.<classname> is unsupported)

P.S. This doesn't really explain your second problem with typealias. It looks like like a bug to me, but I'm not sure.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.