[英]Not coherent behaviour in switch-case statement in Java7 and Java8
我正在准备Java7 Oracle证书,并且想知道为什么Java以这种奇怪的方式处理切换情况:
public static void main(String[] args) {
int a = 2;
switch (a) {
case 0:
//System.out.println(b); // cannot find symbol variable b
break;
case 1:
boolean b=false;
break;
case 2:
b = true; // how case knows about existence of variable b?
break;
case 3:
//System.out.println(b); // var b might not have been initialized
break;
}
}
这很明显为什么情况0和情况3会通知未知符号或未初始化的变量,但是我无法想象为什么情况2可以正常工作? 如果b
在情况1中被分配,编译器如何得知b
的类型? 对我而言,这并不连贯。
UPDATE1:实际上,更奇怪的是,在情况3中,我注意到编译时错误(Linux64,Java7和Java8),但是我的一些同事却没有。
我准备了一个非常简单的Maven项目: https : //github.com/gonciarz/switch-test
UPDATE2:似乎对每个案例case3都不编译。 谢谢你们的澄清。
您正在混合声明和赋值。 在你的代码中
case 1:
boolean b=false;
break;
case 2:
b = true; // how case knows about existence of variable b?
break;
在case 1:
声明和分配变量b
。 声明的范围是switch
语句块的其余部分,即直到}
为止。
就像您写过的一样:
case 1:
boolean b;// declaration
b=false; // assignment
break;
分配对case 2:
标签的代码流无效。 如果发生跳转到case 2
标签,则声明变量但未分配该变量,因为可以跳过一个赋值但不能声明。
因此,该行为与您的第三个标签一致:
case 3:
System.out.println(b); // var b might not have been initialized
break;
在此, 声明了变量b
,但未赋值 。 这就是错误消息告诉您的内容:它不是说未声明b
,而是“可能尚未初始化”,其中包括您肯定知道它尚未被初始化的可能性。
b
的类型是声明的类型,并且不依赖于任何赋值。
作为附带说明, switch
和if
之间有区别。 你写了吗
final int a = 2;
boolean b;
if(a == 2) b=false;
System.out.println(b);
的恒定性质a
引起编译器来检测b
将被分配到false
且没有产生错误。 这适用于if
但不适用于switch
。
您的范围是整个switch子句,而不是单独的情况。 范围由{
和}
定义。
当使用boolean b = false
声明变量时,可以在范围的其余部分(即switch子句的其余部分)中访问它。
您在问题中提到的情况3不会出错。
编辑:在情况3中确实会出现错误,但是Eclipse在检测它时似乎很草率。 我将字段声明与原始变量的默认值与没有的局部变量混淆了。
规则说:
块中的局部变量声明的范围(第14.4节)是该声明在其中出现的其余部分,从其自身的初始化程序开始,并在该局部变量声明语句的右侧包括其他任何声明符。
和这个
声明在编译时处理,并且不依赖于代码的执行流程。 由于value是在switch块的局部范围内声明的,因此从声明的位置开始,该值可在该块中的任何位置使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.