I’ve been reviewing code where some coders have been using redundant ternary operators “for readability.” Such as:
boolean val = (foo == bar && foo1 != bar) ? true : false;
Obviously it would be better to just assign the statement’s result to the boolean
variable, but does the compiler care?
The compiler don't optimize the bytecode because it is optimized at run time by the JIT optimizer. If the type of runtime you are targeting don't have a JIT optimizer (even if it had a JIT compiler), or you are AOT compiling, I recommend using an optimizing obfuscator like Proguard or Allatori.
Moreover, as has been pointed out, at the byte code level there's really no difference between the ternary operator and if-then-else. As in the above example, the decision on which to choose is based wholly on readability.
The conditional ternary operator can definitely be overused, and some find it quite unreadable. However, I find that it can be very clean in most situations that a boolean expression is expected, provided that its intent is clear.
Java ternary operator is the only conditional operator that takes three operands. It's a one-liner replacement for the if-then-else statement and is used a lot in Java programming. We can use the ternary operator in place of if-else conditions or even switch conditions using nested ternary operators.
I find that unnecessary usage of the ternary operator tends to make the code more confusing and less readable, contrary to the original intention.
That being said, the compiler's behaviour in this regard can easily be tested by comparing the bytecode as compiled by the JVM.
Here are two mock classes to illustrate this:
Case I (without the ternary operator):
class Class { public static void foo(int a, int b, int c) { boolean val = (a == c && b != c); System.out.println(val); } public static void main(String[] args) { foo(1,2,3); } }
Case II (with the ternary operator):
class Class { public static void foo(int a, int b, int c) { boolean val = (a == c && b != c) ? true : false; System.out.println(val); } public static void main(String[] args) { foo(1,2,3); } }
Bytecode for foo() method in Case I:
0: iload_0 1: iload_2 2: if_icmpne 14 5: iload_1 6: iload_2 7: if_icmpeq 14 10: iconst_1 11: goto 15 14: iconst_0 15: istore_3 16: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 19: iload_3 20: invokevirtual #3 // Method java/io/PrintStream.println:(Z)V 23: return
Bytecode for foo() method in Case II:
0: iload_0 1: iload_2 2: if_icmpne 14 5: iload_1 6: iload_2 7: if_icmpeq 14 10: iconst_1 11: goto 15 14: iconst_0 15: istore_3 16: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 19: iload_3 20: invokevirtual #3 // Method java/io/PrintStream.println:(Z)V 23: return
Note that in both cases the bytecode is identical, i.e the compiler disregards the ternary operator when compiling the value of the val
boolean.
EDIT:
The conversation regarding this question has gone one of several directions.
As shown above, in both cases (with or without the redundant ternary) the compiled java bytecode is identical.
Whether this can be regarded an optimization by the Java compiler depends somewhat on your definition of optimization. In some respects, as pointed out multiple times in other answers, it makes sense to argue that no - it isn't an optimization so much as it is the fact that in both cases the generated bytecode is the simplest set of stack operations that performs this task, regardless of the ternary.
However regarding the main question:
Obviously it would be better to just assign the statement’s result to the boolean variable, but does the compiler care?
The simple answer is no. The compiler doesn't care.
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