有谁知道为什么:
public void foo()
{
System.out.println("Hello");
return;
System.out.println("World!");
}
在Eclipse下将被报告为“无法到达的错误”,但是
public void foo()
{
System.out.println("Hello");
if(true) return;
System.out.println("World!");
}
仅触发“死代码”警告?
我能想到的唯一解释是Java编译器仅标记第一个,而Eclipse中的一些额外分析则指出了第二个。但是,如果是这种情况,为什么Java编译器在编译时无法弄清楚这种情况?
Java编译器难道不会在编译时发现if(true)无效,从而产生实质上相同的字节码吗?在什么时候应用了可达代码分析?
我猜想一个更一般的思考这个问题的方法是:“何时应用可达代码分析”?在将第二个Java代码片段转换为最终字节码的过程中,我确定在某些时候已删除了“ if(true)”运行时等效项,并且两个程序的表示形式变得相同。Java编译器不会再应用其可达代码分析吗?
第一个原因不能编译(你得到一个错误),第二编译(你只是得到了警告)。就是这样。
关于Eclipse为什么检测死代码的原因,这仅仅是集成开发工具和内置编译器的便利,该编译器与JDK相比,可以更精细地检测这种代码。
更新:JDK实际上消除了无效代码。
public class Test {
public void foo() {
System.out.println("foo");
if(true)return;
System.out.println("foo");
}
public void bar() {
System.out.println("bar");
if(false)return;
System.out.println("bar");
}
}
javap -c
说:
公共类Test扩展了java.lang.Object { public Test(); 代码: 0:aload_0 1:invokespecial#1;//方法java / lang / Object。“” :()V 4:返回 public void foo(); 代码: 0:getstatic#2;//字段java / lang / System.out:Ljava / io / PrintStream; 3:ldc#3; //字符串foo 5:invokevirtual#4; //方法java / io / PrintStream.println:(Ljava / lang / StrV 8:return public void bar(); 代码: 0:getstatic#2; // Field java / lang / System.out:Ljava / io / PrintStream ; 3:ldc#5; //字符串 5:invokevirtual#4; //方法java / io / PrintStream.println:(Ljava / lang / String;)V 8:getstatic#2; //字段java / lang / System.out:Ljava / io / PrintStream; 11:lcd#5;//字符串栏 13:invokevirtual#4; //方法java / io / PrintStream.println:(Ljava / lang / String;)V 16:return }
至于为什么它(Sun)没有给出警告,我不知道:)至少JDK编译器实际上内置了DCE(Dead Code Elimination)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句