I wrote this simple Test
class to see how Java evaluates boolean
algebra at the Bytecode level:
public class Test { private static boolean a, b; public static boolean method1(){ return !(a || b); } public static boolean method2(){ return !a && !b; } }
If you simplify method1()
using DeMorgan's Laws, you should get method2()
. After looking at the Bytecode (using javap -c Test.class), it looks like:
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 }
So my question is, why is method1()
and method2()
exactly the same at the Bytecode level?
What your seeing is a compiler optimization. When javac
encounters method1()
it applies an optimization (based on De Morgan's Laws as you pointed out but also short circuiting the &&
comparison) that allows it to branch early if a
is true
(thus no need to evaluate b
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With