Java scope of a variable

2019-09-05 17:37发布

问题:

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?

回答1:

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.)



回答2:

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}
  }
}


回答3:

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



回答4:

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



回答5:

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



回答6:

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.



标签: java scope