First of all, this is implementation-dependent. The JLS does not specify exactly how a specific snippet or operation must be compiled, as long as the bytecode satistifes the Java Language Specification when run on a VM supporting the Java Virtual Machine specification. A different compiler can generate bytecode that is different from the examples given, as long as it gives the same result when run on a compliant JVM.
On Java 8's javac (1.8.0_65), the code is not the same for the conditional operator, and the if-else.
The ternary operator controls which value is pushed to the stack, and then the value on the top of the stack is stored unconditionally. In this case, if a>b, 42 is pushed and code jumps to the istore, else 59 is pushed. Then whatever value is on top is istored to c.
In the if-else, the conditional controls which istore instruction is actually called.
Notice however that in both cases the instruction is "compare less than or equal" which jumps to the else branch (continuing the if branch otherwise).
Below can be seen the bytecode generated by various compilers. You can get it yourself using the javap tool available in an OpenJDK JDK (example command-line javap -c ClassName)
javac with ternary:
public static void main(java.lang.String...); Code: 0: sipush 169 3: istore_1 4: sipush 420 7: istore_2 8: iload_1 9: iload_2 10: if_icmple 18 13: bipush 42 15: goto 20 18: bipush 69 20: istore_3 21: return
javac with if-else:
public static void main(java.lang.String...); Code: 0: sipush 169 3: istore_1 4: sipush 420 7: istore_2 8: iload_1 9: iload_2 10: if_icmple 19 13: bipush 42 15: istore_3 16: goto 22 19: bipush 69 21: istore_3 22: return }
However, with ecj, the code is even more odd. Ternary operator conditionally pushes one or the other value, then pops it to discard it (without storing):
Code: 0: sipush 169 3: istore_1 4: sipush 420 7: istore_2 8: iload_1 9: iload_2 10: if_icmple 18 13: bipush 42 15: goto 20 18: bipush 69 20: pop 21: return
ecj with if-else somehow optimizes out the pushes/stores but still includes an oddball comparison (mind you, there are no side effects to the comparison that need to be retained):
Code: 0: sipush 169 3: istore_1 4: sipush 420 7: istore_2 8: iload_1 9: iload_2 10: if_icmple 13 13: return
When I add a System.out.println(c) to foil this unused-value discard, I find that the structure of both statements is similar to that of javac (ternary does conditional push and fixed store, while if-else does conditional store).