我编写了这个简单的Test类,以查看boolean代数是如何在字节码级别计算的:
public class Test {
private static boolean a, b;
public static boolean method1(){
return !(a || b);
}
public static boolean method2(){
return !a && !b;
}
}如果您使用method1()简化了德摩根定律,那么您应该得到method2()。查看了字节码(使用javap -c Test.class)后,如下所示:
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":
()V
4: return
public static boolean method1();
Code:
0: getstatic #2 // Field a:Z
3: ifne 16
6: getstatic #3 // Field b:Z
9: ifne 16
12: iconst_1
13: goto 17
16: iconst_0
17: ireturn
public static boolean method2();
Code:
0: getstatic #2 // Field a:Z
3: ifne 16
6: getstatic #3 // Field b:Z
9: ifne 16
12: iconst_1
13: goto 17
16: iconst_0
17: ireturn
}所以我的问题是,为什么method1()和method2()在字节码级别完全相同?
发布于 2013-10-31 17:57:58
你看到的是编译器优化。当javac遇到method1()时,它应用了一个优化(正如您所指出的那样,它基于德摩根定律,但也短路了&&比较),如果a是true (因此不需要评估b),它可以尽早分支。
发布于 2013-10-31 18:12:48
为什么
method1和method2在字节码级别是相同的?
你自己已经很好地回答了这个问题,指出了这两种方法的等价性,如果其中一种方法应用了De的变换。
但是为什么
method1看起来像method2而不是method2看起来像method1呢?
这个假设是不正确的:并不是method1看起来像method2或者method2看起来像method1:相反,这两种方法看起来都像一些methodX,看起来如下所示:
public static boolean methodX() {
if (a) {
return false;
}
return !b;
}由于短路,这两种方法都简化为该逻辑.优化器然后将两个ireturn分支合并,将gotos插入到不同的标签中。
发布于 2013-10-31 18:11:53
就像你说的,这两种方法表示相同的数学。一个特定的编译器如何产生字节码取决于编译器作者,只要它是正确的。
编译器是否应用了DeMorgan的定律一点也不确定。在我看来,可能有一些更简单的优化技术会导致同样的优化。
https://stackoverflow.com/questions/19713453
复制相似问题