Recently i started reading java language specification and moved to section "Field Access Expressions".
I came to know few java basics after programming >3 1/2 yrs in java.Pity.Never mind atleast learnt now.
Have a look at this class and can you predict the output?
class S {
int x = 0;
protected void m1() {
System.out.println("In S m1()");
}
public void m2() {
System.out.println("In S m2()");
}
public void m3(int x) {
this.x=x;
}
}
class T extends S {
int x = 1;
protected void m1() {
System.out.println("In T m1()");
}
public void m2() {
System.out.println("In T m2()");
}
public void m3(int x) {
this.x=x;
}
}
class PrimaryExpressions {
public static void main(String[] args) {
T t = new T();
System.out.println("t.x=" + t.x);
S s = new S();
System.out.println("s.x=" + s.x);
s = t;
System.out.println("s.x=" + s.x);
s.m2();
s.m3(s.x);
System.out.println("s.x=" + s.x);
System.out.println("t.x=" + t.x);
t.m3(s.x);
System.out.println("s.x=" + s.x);
System.out.println("t.x=" + t.x);
}
}
Well i hope and strongly believe that you are not like me and got predicted output only. Good.For guys who are sailing with me in the same ship well not a problem atleast we are learning now.
Output:
t.x=1
s.x=0
s.x=0
In T m2()
s.x=0
t.x=0
s.x=0
t.x=0
Why s.x=0 prints 0 even though we assigned T instance to S?
If we have a close look at the Java language specification what it states:
Primary expressions : Include most of the simplest kinds of expressions, from which all others are constructed: literals, class literals, field accesses, method invocations, and array accesses. A parenthesized expression is also treated syntactically as a primary expression.
PrimaryNoNewArray:
Literal
Type . class
void . class
this
ClassName.this
( Expression )
ClassInstanceCreationExpression
FieldAccess
MethodInvocation
ArrayAccess
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.
The field that is accessed does not depend on the run-time class of the referenced object; even if s holds a reference to an object of class T, the expression s.x refers to the x field of class S, because the type of the expression s is S.Objects of class T contain two fields named x, one for class T and one for its superclass S.
The power of late binding and overriding is available, but only when instance methods are used.
Now when you navigate to classes section it states:
If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class.
The field declaration also shadows declarations of any accessible fields in enclosing classes or interfaces, and any local variables, formal method parameters, and exception handler parameters with the same name in any enclosing blocks.
Hence even though we declare an innerClass in S
class S {
int x = 0;
class InnerClassS {
int x=100;
void incrementX() {
System.out.println("In InnerClassS m1()" + x);
x=x+1;
}
}
}
and try to call
s.new InnerClassS().incrementX();
System.out.println("s.x=" + s.x);
It always prints 0.
If a field declaration hides the declaration of another field, the two fields need not have the same type.
So it does not matter of the data type declared for the field like
class InnerClassS {
// int x=100;
double x=100;
......
Hope this explanation helps.
Any suggestions/Comments well Appreciated.
Wednesday, 22 August 2007
Subscribe to:
Post Comments (Atom)
2 comments:
Nice Blog. Keep up the good work!
Andy Hardy
Andy,
Thanks a lot.
Sorry for late reply.Hope you are fine in Australia.
Thanks
Prashant
Post a Comment