有谁知道为什么:
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 编译器不会再次应用其可达代码分析吗?
第一个是not编译(您收到错误),第二个编译(您刚刚收到警告)。这就是区别。
至于为什么 Eclipse 会检测死代码,嗯,这只是带有内置编译器的集成开发工具的便利性,与 JDK 相比,它可以进行更多微调来检测此类代码。
Update: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
says:
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public void foo();
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String foo
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/StrV
8: return
public void bar();
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #5; //String bar
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #5; //String bar
13: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return
}
至于为什么它(Sun)没有给出警告,我不知道:)至少 JDK 编译器实际上内置了 DCE(死代码消除)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)