I've just read through Java bytecode instruction listings and wondered:
What is the difference between ifne
and ifnonnull
in Java Bytecode?
I know that in a high level language (e.g. Java) the value 0
is an numeric value that has some operations (like addition, subtraction, multiplication) and can be compared to other numeric values whereas null
is a value that represents "no value".
I guess one problem I have is that I don't know how null
might be represented in Bytecode / assembly.
The JVM specification is perhaps clearer on this.
So for ifne
(and ifeq
etc) the restriction is:
An
ifeq
instruction is type safe iff one can validly pop a type matching int off the incoming operand stack yielding the outgoing type state NextStackFrame, and the operand of the instruction, Target, is a valid branch target assuming an incoming type state of NextStackFrame.
Whereas for ifnonnull
the restriction is:
An ifnonnull instruction is type safe iff one can validly pop a type matching reference off the incoming operand stack yielding the outgoing type state NextStackFrame, and the operand of the instruction, Target, is a valid branch target assuming an incoming type state of NextStackFrame.
Basically ifeq
and ifne
are for integer values, whereas ifnonnull
is for a reference value.
To compare two references for equality, you use if_acmpeq
instead. ifnonnull
is effectively a special case of that where there's only one operand, because it's always just compared with null.
In terms of how the null
reference is represented in data, the JVM specification explicitly allows this to be implementation-specific:
A reference value may also be the special null reference, a reference to no object, which will be denoted here by null. The null reference initially has no run-time type, but may be cast to any type. The default value of a reference type is null.
The Java Virtual Machine specification does not mandate a concrete value encoding null.
See more on this question at Stackoverflow