I do not understand why the output of this code is 10
:
package uno;
public class A
{
int x = 10;
A(){int x = 12; new B();}
public static void main(String args[]){
int x = 11;
new A();
}
class B{
B(){System.out.println(x);}
}
}
How does the scope in this example work? Why System.out.println(x);
prints 10? Is it because the instruction System.out.println(x);
is outside the parentesis of the costructor: A(){int x=12; new B();}
and so int x = 12
lives only there but when System.out.println(x);
is invoked, x = 12
lives no longer?? So the first x
is x=10
declared in class A
? What if there were any x
in class A
? Would it print 11
?
Local variables can only be accessed from within the method they are declared. With this in mind, the code can be rewritten to avoid shadowing the member variables and the resulting confusion:
package uno;
public class A{
// And instance member variable (aka field)
int field_A_x = 10;
A(){
// A local variable, only visible from within this method
int constructor_x = 12;
new B(); // -> prints 10
// Assign a new value to field (not local variable), and try again
field_A_x = 12;
new B(); // -> prints 12
}
public static void main(String args[]){
// A local variable, only visible from within this method
int main_x = 11;
new A();
}
class B{
B(){
// The inner class has access to the member variables from
// the parent class; but the field not related to any local variable!
System.out.println(field_A_x);
}
}
}
(Shadowed member variables can always be accessed in the this.x
notation; but I would suggest not shadowing variables - choose meaningful names.)
int x = 10;
This has instance scope, any member of class A can "see" this. Class B sees this.
int x=12;
This has local scope, within your A constructor. It is only seen inside the constructor of A.
int x = 11;
Also with local scope, this time, inside your main method.
Who does System.out.println(x);
? The constructor of B. What does B see? int x = 10;
.
That's why...
Furthermore,,
public class A{
int x = 10;
A(){int x=12; new B(); System.out.println(x); //prints 12}
public static void main(String args[]){
int x = 11;
System.out.println(x); // prints 11
new A();
}
class B{
B(){System.out.println(x); //prints 10, as in your example}
}
}
Try out what happens if you leave out the int
in your 4th line:
package uno;
public class A{
int x = 10;
A(){x=12; new B();}
public static void main(String args[]){
int x = 11;
new A();
}
class B{
B(){System.out.println(x);}
}
}
Then the output will be 12, because you do not initialize a new int x
Your inner class cant see local variables which you define in the constructor of the A class. This is why x is 10 for B.
EDIT: Ninja'd
If you are expecting output as x=12
, just change
A(){int x=12; new B();} // remove int here
to
A(){x=12; new B();}
It is currently creating a local variable
, as it is declared inside a method.
Removing new declaration inside constructor, will change instance variable
's value.
So output will be x=12
what is happening is variable shadowing. Check http://en.wikipedia.org/wiki/Variable_shadowing
if variable with same name is declared and initialized in local method then that value is used only in the method it is defined in. It does not change global variable variable. So setting int x = 11
or int x = 12
does not change global value of x. However in a method if variable is not defined global value is used so in class B
global value of x i s printed.