Kiah Starck
Kiah Starck

Reputation: 47

Why can't I refer enclosing class's non-static var from its inner class's non-static method?

In my awareness, non-static method will be assigned "this" variables for its class obj & all enclosing classes.

public class TestNested {

int a=4;

public static class a{

    int a=5;

    static int c=10;

    class b{

        int a=6;

        void aaa(){

            int a=7;

            TestNested t=new TestNested();

            System.out.println(this.a);

            System.out.println(b.this.a);

            System.out.println(TestNested.a.b.this.a);

            System.out.println(TestNested.a.this.a);

            System.out.println(a.this.a);

            System.out.println(t.a);

            System.out.println(TestNested.this.a);

        }
    }
}

void r(){

    TestNested t=new TestNested();

    TestNested.a a=new TestNested.a();

    a.b b=a.new b();

    b.aaa();
}

public static void main(String[] args) {

    TestNested t=new TestNested();

    t.r();
}
}

in this case the final statement of void aaa() is System.out.println(TestNested.this.a); will be sentenced to cause compilation error with the reason :'com.xxx.TestNested.this' cannot be referenced from static context, that's really confusing me because the this var that points to TestNested should be the non-static hidden var of the method itself,then why it can't use its own var?

Or if my awareness is wrong that each that var is assigned in each class enclosed from the method's class, but the void aaa() isn't a static method which means it can reference non-static var rite? or even the method isn't static, but if one of its enclosing class is static, it'll be automatically recognized as static member?

Upvotes: 1

Views: 304

Answers (2)

Joffrey
Joffrey

Reputation: 37680

This is because your nested class a is not an inner class of TestNested. It is a static nested class, meaning that it is not linked to a particular instance of TestNested.

Note: an inner class is a non-static nested class.

What instance of TestNested would you expect your expression TestNested.this to refer to?

You can see, by the way, that you're not referring to your variable t here:

TestNested.a a=new TestNested.a();

Which points out that the object a is not linked to t at all.


In my above answer, I assumed it was clear to you what you were doing with this. It appears it is not the case, according to your comments, so I'm going to try and clarify it here.

First of all, this always refers to an object: an instance of a class.

Let's assume we're in the context of a non-static method in the class b. Because the method is non-static, the code will be executed relatively to a particular instance of b. I take the shortcut to refer to this particular instance as "the instance of b you're in".

Since b is an inner class of a, no instance of b can exist outside an instance of a. This means the instance of b you're in is enclosed in an instance of a. I take the shortcut to refer to this particular instance as "the instance of a you're in" (Technically, you're in a b which is in an a).

So, in this context of a non-static method of b:

  • this refers to the instance of the b you're in. It is the standard use of this keyword.
  • b.this, a.b.this or TestNested.a.b.this are the same as this here, the difference is only that you qualify more precisely the class b.
  • a.this or TestNested.a.this both refer to the instance of a you're in (TestNested.a is just a more precise qualification for a). This a object exists because b is an inner class of a, which means that every instance of b is linked to an instance of a. This is the only way to refer to the instance of a.
  • TestNested.this would refer to the instance of TestNested you're in. But you're not in any instance of TestNested, so it does not mean anything, hence the compile error. You're in an instance of b, which is within an instance of a (because b is an inner class of a). The instance of a exists by itself because a is a static nested class of TestNested, so it is not linked to an instance of TestNested.

Upvotes: 4

sinclair
sinclair

Reputation: 2861

TestNested.a <-- references a static variable of a static class

this.a <-- references an instance variable of an object

TestNested.this <-- tries to reference an object from a static context, but "this" does not exist in a static context.

You can reference static content from non-static, but not vice-versa.

Upvotes: 0

Related Questions