pol*_*nts 31 java eclipse null enums switch-statement
我正在尝试enum
,我发现以下编译并在Eclipse上运行正常(Build id:20090920-1017,不确定编译器版本):
public class SwitchingOnAnull {
enum X { ,; }
public static void main(String[] args) {
X x = null;
switch(x) {
default: System.out.println("Hello world!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
在使用Eclipse编译和运行时,这将"Hello world!"
正常打印和退出.
使用javac
编译器,这NullPointerException
将按预期抛出.
那么Eclipse Java编译器中是否存在错误?
pol*_*nts 27
这是一个错误.这是switch
根据Java语言规范第3版的语句的指定行为:
switch
声明Run Code Online (Sandbox Code Playgroud)SwitchStatement: switch ( Expression ) SwitchBlock
switch
执行语句时,首先Expression
评估该语句.如果Expression
求值为null
,NullPointerException
则抛出a并且整个switch
语句因此而突然完成.
显然,Eclipse中的错误与default
case 无关或完全无关enum
.
public class SwitchingOnAnull {
public static void main(String[] args) {
java.math.RoundingMode x = null;
switch(x) {};
switch((Integer) null) {};
switch((Character) null) {
default: System.out.println("I've got sunshine!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码编译并在Eclipse(至少某些版本)上运行"正常".每个人在编译时都会switch
抛出一个,这与规范要求完全一致.NullPointerException
javac
这是javap -c SwitchingOnAnull
在Eclipse下编译的时候:
Compiled from "SwitchingOnAnull.java"
public class SwitchingOnAnull extends java.lang.Object{
public SwitchingOnAnull();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
5: ldc #22; //String I've got sunshine!
7: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
}
Run Code Online (Sandbox Code Playgroud)
似乎Eclipse编译器switch
完全摆脱了整个构造.不幸的是,这种优化打破了语言规范
该错误已被提交并分配用于修复.
Olivier Thomann 2010-05-28 08:37:21 EDT
我们在优化方面过于激进.
对于:
Run Code Online (Sandbox Code Playgroud)switch((Integer) null) {};
switch
当我们至少应该评估表达式时,我们会优化整个语句.我会看一看.
候选人为3.6.1.