As usually is for different compilers, it is also in the Java case: the result must be the same but the way it is reached can be (from the bytecodes point of view) different., e.g. because of optimizations or alike. The JVM is stack based V machine; the following is an imaginary example (I don't know jvm mnemonics for the instructions opcodes)
push 10
push 20
add
push 19
push 1
add
push 10
add
These produce same result, but generated bytecodes are different (the first is slightly optimized, the second is "totally" not optimized; a third option could be push 30
since we are adding known (likely at compiletime) constants). This is a simple case, but more complex case can be easily built.