Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I cannot refer to a nested object from val or typealias referring to an object?

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 cannot refer to a nested object (in an outer object) using val or typealias which are referring to the outer object. Why?

like image 907
Naetmul Avatar asked Jun 09 '17 10:06

Naetmul


2 Answers

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.

like image 80
voddan Avatar answered Oct 19 '22 12:10

voddan


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.

like image 41
holi-java Avatar answered Oct 19 '22 10:10

holi-java