Java开关:变量声明和作用域
Java编译器如何处理以下开关块? “b”变量的范围是什么 请注意,“b”变量仅在switch语句的第一个分支中声明。试图在第二个分支中声明它也会导致“复制局部变量”编译错误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
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
;-)