Class scope variable vs method scope variable

2019-02-28 00:45发布

问题:

I know that variable scope is enclosed by a start of block { and an end of block }. If the same variable is declared within the block, then the compile error Variable already defined occurs. But take a look at following example.

public class Test{
int x=0;// Class scope variable

public void m(){
  int  x=9;   //redeclaration of x is valid within the scope of same x. 

  if(true){
      int x=7; // but this redeclaration generates a compile time error.
  }

}

Here, x can be redeclared in a method, although it's already declared in the class. But in the if block, x can't be redeclared.

Why is it that redeclaration of a class scope variable doesn't generate an error, but a method scope variable redeclaration generates an error?

回答1:

This is because int x=0 is not a variable but an instance field. Local variables are allowed to have the same names as fields. To distinguish between a variable and a field with the same name we use this prefix for instance fields or class name for class fields. E.g.

int x = this.x


回答2:

Because that's the way Java was designed. The language designers could easily have made it so that it was impossible to use the same name for a local variable and an instance variable. They simply chose not to.



回答3:

Here is a good example of java scopes (from OCA java SE-7). Here z(class variable) is initialized inside the method, doStuff2. Class variables can be initialized inside the method but if the same variable is re-declared inside a method, a new local variable is created on the stack instead of the heap.

            public class ScopeTest
            {
            int z;
            public static void main(String[] args){
            ScopeTest myScope = new ScopeTest();
            int z = 6;
            System.out.println(z);
            myScope.doStuff();
            System.out.println(z);
            System.out.println(myScope.z);
            }
            void doStuff() {
            int z = 5;
            doStuff2();
            System.out.println(z);
            }
            void doStuff2()
            {
            z = 4;
            }
            }

The output:

6 
5 
6 
4