Gre*_*reg 22 java compiler-construction if-statement language-lawyer
获取以下Java代码段:
....
else if (true){ //hard-coded as true
///launch methodA
}
else {
///launch methodA (same code as in the ` else if ` statement)
}
....
Run Code Online (Sandbox Code Playgroud)
我想知道的是编译器如何处理这个问题.编译器else if(true)完全删除语句以便不必执行检查是不合逻辑的,即使它被硬编码为真.特别是在Eclipse中,上面的代码是如何解释的?
或者在以下场景中如何:
....
else if (true){ //hard-coded as true
///launch methodA
}
else {
///launch methodBB
}
....
Run Code Online (Sandbox Code Playgroud)
在这种情况下编译器删除else语句不是合乎逻辑的吗?因为在运行时,else语句无法访问.
dot*_*vav 21
Java中禁止使用无法访问的语句,并且必须触发编译错误.JLS定义了什么是无法访问的语句:https: //docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21
在这里完全引用它太长了,但这里有一个摘录(强调我的):
Run Code Online (Sandbox Code Playgroud)if (false) { x=3; }不会导致编译时错误.优化编译器可以 实现语句x = 3; 将永远不会执行,并可能选择从生成的类文件中省略该语句的代码,但语句x = 3; 在此处指定的技术意义上,不被视为"无法到达".
这种不同处理的基本原理是允许程序员定义"标志变量",例如:
Run Code Online (Sandbox Code Playgroud)static final boolean DEBUG = false;然后编写如下代码:
Run Code Online (Sandbox Code Playgroud)if (DEBUG) { x=3; }我们的想法是,应该可以将DEBUG的值从false更改为true或从true更改为false,然后正确编译代码而不对程序文本进行其他更改.
所以答案取决于您使用的编译器及其优化选项.
Jea*_*art 10
编译器在编译时优化它:
public class Test {
public static void main(String[] args) {
if(true) {
System.out.println("Hello");
} else {
System.out.println("Boom");
}
}
Run Code Online (Sandbox Code Playgroud)
给我(和我一起Java 1.8.0_45):
Compiled from "Test.java"
public class Test {
publicTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
Run Code Online (Sandbox Code Playgroud)
代码只是打印Hello.Boom甚至没有考虑过.
所有最新的Java编译器都在编译时消除了死代码.
| 归档时间: |
|
| 查看次数: |
2156 次 |
| 最近记录: |