Block scope variables

2020-02-05 03:44发布

This will compile

class X
{  
    public static void main(String args[])
    {
        {
            int a = 2;
        }
        {
            int a = 3;
        }       
    }
}

This won't

class X
{  
    public static void main(String args[])
    {

        int a = 2;

        {
            int a = 3;
        }       
    }
}

I expected both to compile (maybe it is the way C works?). What is the reason because it is not possible to declare a variable in a block with the same name of one in the outer block?

5条回答
叛逆
2楼-- · 2020-02-05 03:52

Java doesn't allow you to have two variables with the same name within scope of one another.

In your second case:

int a = 2;

{
  // the outer 'a' is still in scope
  int a = 3; // so this is a redeclare <-- nooo!
} 

However, in your first case, each a is contained within its own scope, so all is well.

查看更多
爷、活的狠高调
3楼-- · 2020-02-05 03:54
public static void main(String args[])
{
    int a = 2; // I know a
    // I know a
    {
        // I know a
        int a = 3; // There can be only one a!
    }       
}

In the example above you declared a in you method main(). From the declaration till the end of the method, a is declared. In this case you cannout redeclare a in you codeblock.

Below, you declare a in a block. It is only known insside.

public static void main(String args[])
{
    { 
        int a = 2; // I know a
        // I know a
    }
    // Who is a?
    {

        int a = 3; // I know a!
    }       
}
查看更多
beautiful°
4楼-- · 2020-02-05 04:03

Because in the second case a is known inside the static block, so you're trying to redeclare it. The compiler doesn't allow you to do so:

public static void main(String args[]) {
    {
       int a = 2; //a is known only here
    }             //a will be freed
    {
       int a = 3; //you can declare it again here
    }       
}
查看更多
beautiful°
5楼-- · 2020-02-05 04:15

The short answer is: Because this is the way the Java language is defined in JLS §6.4.

You might be used from other languages that this so called variable shadowing is allowed. However, the inventors of the Java languages thought this was an awkward feature that they did not want in their language:

This restriction helps to detect some otherwise very obscure bugs.

However, you find shadowing elsewhere in Java as the authors state in the same section of the JLS:

A similar restriction on shadowing of members by local variables was judged impractical, because the addition of a member in a superclass could cause subclasses to have to rename local variables. Related considerations make restrictions on shadowing of local variables by members of nested classes, or on shadowing of local variables by local variables declared within nested classes unattractive as well.

This means in practice that the following code is legal:

class A {
   int x = 0;
   void m() {
     int x = 10; // Shadows this.x
   }
}

As the authors describe, it is allowed to shadow an instance variable by declaring a method local variable with the same name because of the possibility of someone extending the functionality of A at one day where you could not longer compile a class B if shadowing was illegal:

class B extends A {
   void m() {
     int x = 10; // Shadows A.this.x if A declares x
   }
}

If you consider a language like C, where shadowing is allowed, you can find awkward code like this:

int x;
int main() 
{
  {
    int x = 0;
    {
      extern int x;
      x = 1;
    }
    printf("%d\n", x); // prints 0
  }
  printf("%d\n", x); // prints 1
  return 0;
}

This program is not so easy to follow and might therefore not produce the results you expect, thanks to variable shadowing.

查看更多
beautiful°
6楼-- · 2020-02-05 04:15

In Java all local variables will be stored on Stack. So if u write

class X
{  
public static void main(String args[])
{
   int a = 2;    // At this point var 'a' is stored on Stack
   {
       /*
       Now as the prev. 'main method is not yet complete so var 'a' is still present on the Stack. So at this point compiler will give error "a is already defined in main(java.lang.String[])" 
        */
       int a = 3;   

   }
 }
}

Hope this help you out

Thanks

查看更多
登录 后发表回答