From JLS 15.8.3 When used as a primary expression, the keyword this denotes a value, that is a reference to the object for which the instance method was invoked (�15.12), or to the object being constructed.
The definition of this keyword looks pretty straight forward in this section of JLS. But if you look at this code, it seems to have violated that same definition.
Line 1 will call B.m2(), which is expected because this refers to the object b of class B. But at line 2, it will refer to A.j variable. I would expect it to refer to B.j because that is the object that invoked the method m2(). In fact, there is only one object here, which is an instance of B. So why is it behaving like this?
Member variables are evaluate considering the reference type, and member functions are evaluated considering the instance (i.e. behaves polymorphically). In your example if you construct: A a = new B(); System.out.println(a.j); // you get the value 1 (so the value from class A, which is the type of your reference) // if for e.g. you cast the reference to the B type, then you get value 10. e.g. System.out.println(((B)a).i);
Also, from JLS 15.8.3, The type of this is the class C within which the keyword this occurs.
In class A, the compile-time type of �this� is A. In class B, the compile-time type of �this� is B. By JLS 15.11.1, only the type of the Primary expression, not the class of the actual object referred to at run time, is used in determining which field to use. [ June 23, 2003: Message edited by: Marlene Miller ]
Joined: Mar 05, 2003
Hi Alton, I was curious about and unsure of 15.8.3 myself a while ago. So I played around with this. I posted a few quizzes for other people to think about. 1 quiz on this, 6 quizzes on this [ June 23, 2003: Message edited by: Marlene Miller ]
Joined: May 30, 2003
Thanks again Marlene. I totally ignored that part of JLS 15.8.3. I thought it has no direct bearing on the code. But when you point out JLS 15.11.1 then everything fits together.