Java开关:变量声明和作用域

Java开关:变量声明和作用域,java,scope,initialization,switch-statement,variable-declaration,Java,Scope,Initialization,Switch Statement,Variable Declaration,Java编译器如何处理以下开关块? “b”变量的范围是什么 请注意,“b”变量仅在switch语句的第一个分支中声明。试图在第二个分支中声明它也会导致“复制局部变量”编译错误 int a = 3; switch( a ) { case 0: int b = 1; System.out.println("case 0: b = " + b); break; case 1: // the followin

Java编译器如何处理以下开关块? “b”变量的范围是什么

请注意,“b”变量仅在switch语句的第一个分支中声明。试图在第二个分支中声明它也会导致“复制局部变量”编译错误

    int a = 3;
    switch( a ) {
    case 0:
        int b = 1;
        System.out.println("case 0: b = " + b);
        break;
    case 1:
        // the following line does not compile: b may not have been initialized
        // System.out.println("case 1 before: b = " + b);
        b = 2;
        System.out.println("case 1 after: b = " + b);
        break;
    default:
        b = 7;
        System.out.println("default: b = " + b);
    }

注意:上面的代码是用java 1.6编译器编译的。

与往常一样,作用域由
{
}
分隔。
b
的作用域是块。您只有一个包含所有
案例的块。这就是为什么在第二个
案例中重新声明
b
时会出现编译错误

您可以将每个
案例
包装在自己的块中,如

case 0:
   {
     int b = 1;
     ...
   }
case 1:
   {
     int b = 2;
     ...
   }

但我认为FindBugs或CheckStyle会对此抱怨。

您的
案例
块没有任何局部范围。它不是一系列的
if
..
else if
..
else
块,java将它实现为一系列的
GOTO
s。

b
的范围是切换块-在声明和分隔符之间
-

int a = 3;

switch( a ) {
     case 0:
          int b = 1; //scope starts
          System.out.println("case 0: b = " + b);
          break;
     case 1:
          // the following line does not compile: b may not have been initialized
          // System.out.println("case 1 before: b = " + b);
          b = 2;
          System.out.println("case 1 after: b = " + b);
          break;
     default:
          b = 7;
          System.out.println("default: b = " + b);
}//scope ends
但是,您需要知道,如果您在
案例1:
中声明
int b
,您将无法访问
案例0:
中的变量
b

要回答您在java注释中提出的问题,可以查看以下更简单的示例:

int b;
if(true){
    b++; //The local variable b hast not been initialized
}

希望有帮助。

在您的代码中,如果a不等于0,b将永远不会被初始化。您应该在switch语句之前定义b。

switch()
语句中定义的变量范围将与正常块中定义的变量范围相同,正常块由
{
}
包围


因此,在
switch()
语句中定义的每个变量在定义后对整个块都是可见的。

您可以使用案例周围的{}来定义范围

int a = 3;
switch( a ) {
case 0: {
    int b = 1;
    System.out.println("case 0: b = " + b);
    break;
}
case 1: {
    // the following line does not compile: b may not have been initialized
    // System.out.println("case 1 before: b = " + b);
    int b = 2;
    System.out.println("case 1 after: b = " + b);
    break;
}
default: {
    int b = 7;
    System.out.println("default: b = " + b);
}
}

给OP的消息是,你们可以在每个箱子周围放上大括号,这样它就可以工作了。在
案例1:{doHere();break;}
中,问题是在编译时,而不是在运行时。编译错误不是因为重新声明
b
,而是因为在初始化之前访问它
b
在案例0、1和默认情况下完全有效,因为正如您所提到的,它在范围内。他的注释行未编译的问题是b在被访问之前没有初始化。我应该更仔细地阅读这个问题。我以为他在注释掉的行中做了
intb=2
;-)