繁体   English   中英

Java7和Java8中的switch-case语句中的行为不一致

[英]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类型声明的类型,并且不依赖于任何赋值。


作为附带说明, switchif之间有区别。 你写了吗

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM