简体   繁体   中英

Why can't we get access from the inner's class constructor to another inner class?

class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
    }

    public class SuperInner{
        int a;
    }

    public class Inner{
        public class MegaInner{
            public MegaInner(){
                Main.SuperInner.this.a = 6; //error: not an enclosing class: Main.SuperInner
            }
        }
    }
}

IDEON

What JLS says is:

Let C be the class denoted by ClassName. Let n be an integer such that C is the n'th lexically enclosing class of the class in which the qualified this expression appears.

[...]

It is a compile-time error if the current class is not an inner class of class C or C itself.

In the case C:=Main , the set of inner classes S := {SuperInner, MegaInner, Inner} . Which means the code above should work fine. What's wrong?

One could have multiple instances of SuperInner , as well as of Inner or MegaInner . Calling Main.SupperInner.this.a from within MegaInner , it wouldn't be clear which instance (if there is an instance at all) should have the a variable set to 6.

The inner classes behave much like normal classes: one always needs an instance to set a variable in them. Main.SuperInner.this does not denote an instance from MegaInner 's view, as this only refers to the class-hierarchy of MegaInner , which SuperInner is not a part of.

The "Qualified this" expression Main.SuperInner.this.a appers inside MegaInner .

The enclosing classes of MegaInner are Inner and Main . So this is the 0th qualified this , Inner.this is the 1st qualified this, and Main.this is the 2nd qualified this.

The part you were missing is that it has to be an enclosing class of the class where the expression with the this appears. SuperInner is not an enclosing class of MegaInner and therefore the Qualified this does not apply to it.

Think about it in reality. A this expression refers to an instance of the class. It does not refer to the class itself. You cannot refer to this from a static method, for example.

Now, when you create an instance of MegaInner , it has to be part of an actual instance of Inner and an actual instance of Main . But there is no guarantee that there is an actual instance of SuperInner . The code of the enclosing classes may create objects of type SuperInner at any time and independently of instances of Inner .

Thus, you can't access a this of it at compile time. But if you are given an instance of it through a reference variable, you are allowed to access the variable a , as they are all members of the same outer class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM