1

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?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • 5
    Please rename your class `a` in CamelCase. It is very hard to explain things if you're using the same names for classes, variables and fields. – Joffrey Jun 12 '15 at 18:05

2 Answers2

4

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.
Joffrey
  • 32,348
  • 6
  • 68
  • 100
  • Hi, thx so much for ur explaining, but I still have a question about it, I'm fully aware that the static nested class is actually a top-level class when u need to use it, but if it's really in the top-level of class hierarchy, then why can we still use `TestNested.a.b.this.a` to refer the `static class a` & its members? – Kiah Starck Jun 14 '15 at 11:16
  • This is just a matter of namespace. `TestNested.a.b.this` just refers to the instance of `TestNested.a.b` you're in. You could have used simply `this` and it would have had the same effect in this case. – Joffrey Jun 14 '15 at 22:37
  • Thx so much @Joffrey , so can I make the conclusion as the following: In the aspect of code structure, `TestNested` is still the the enclosing class of `a`, but for usage, it's actually the top-leveled class of `b`? I think it's actually a design bug, cuz if `a` is seen as top-level, then we should can't refer `a` & `b` through `TestNested`? Doesn't make any sense!! – Kiah Starck Jul 12 '15 at 14:03
  • @KiahStarck I don't understand what you mean by *"it's actually the top-leveled class of* `b` *"* . `a` is a static nested class of `TestNested` (not linked to a particular instance of it), and `b` is an inner class of `a`. So the hierarchy is respected, `a` is not *"seen as top-level"*. – Joffrey Jul 12 '15 at 14:07
  • @KiahStarck Could you please explain what exactly does not make sense? I find that everything is really logical here. I don't get where you see a design "bug". – Joffrey Jul 12 '15 at 14:09
  • @KiahStarck My apologies, I didn't expect you to interpret an aggressive tone in my comment, I wasn't at all ;-) I just don't understand what you don't understand here, and I was merely asking for clarification. And your last comment still didn't help. Did you mean `TestNested`? Yes you can refer to `a` in `TestNested`, but what is wrong with that? – Joffrey Jul 13 '15 at 11:41
  • sry man that's a unfinished comment which was wrongly sent, thx so much again for ur help!! – Kiah Starck Jul 13 '15 at 12:54
  • calm down man I rethink abt it, first let me clean one thing that ur "linked to `TestNested` " means my `this` assigned to non-static method rite? If it's rite, can I think this as: static nested class is also an static member of `TestNested`, so it & its member(even a non-static method of its nested class) can't be assigned "this", so my case happens, rite? And this is the same reason of ur " static nested cannot be linked to `TestNested` rite? – Kiah Starck Jul 13 '15 at 12:58
  • @KiahStarck I just realized that you were not really comfortable with the expression `Something.this`. `this` is not a field, it is just a keyword referring to the object you're in, or to be more precise, the non-static context of the code that calls it. I updated my answer to clarify. – Joffrey Jul 13 '15 at 14:07
0

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
sinclair
  • 2,812
  • 4
  • 24
  • 53
  • sry mate, really don't understand these two parts: **TestNested.a is static class + static variable** **this.a is non-static + static variable** and in this part **TestNested.this tries to reference non-static content (this) from static context.** , that's also my question point which was asking that is `void aaa` also a static method bcuz it's enclosing is static even it's not declared as static method? – Kiah Starck Jun 14 '15 at 11:23
  • *TestNested.this <-- tries to reference an object from a static context, but "this" does not exist in a static context.* -- this is not always true. `ClassName.this` is also a syntax used in an inner class to refer to its enclosing object. This is exactly what confuses the OP here, because we are currently in a static nested class, and not in an inner class. For instance: http://stackoverflow.com/questions/4080868/using-this-with-class-name – Joffrey Jun 16 '15 at 12:30
  • @sinclair thx so much, I fully understand now, actually I thought abt it in my discussion with Joffrey above lol! I think that's the reason bcuz static nested class is also an static member to `TestNested`, so it & its members(even a non-static method of one of its nested class) won't be assigned `this` var for its enclosing, just like the situation of the normal class(no nested class situation), static method won't have `this` var for its located class's members, is that what u mean? thx!! – Kiah Starck Jul 13 '15 at 13:21
  • @Joffrey I think sinclair's answer is what I wanna say to u above lol, but seems like it's not always true according to you, but we can't reference `TestNested` from `a`'s inner by `this` var still?btw what's OP u said? thx! – Kiah Starck Jul 13 '15 at 13:32
  • @KiahStarck OP means Original Post(er), that's you ;-) I'll update my answer to clarify the usage of `this`. – Joffrey Jul 13 '15 at 13:58