Why is a Java array index expression evaluated before checking if the array reference expression is null?
An array access expression has two sub-expressions:
An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets).
The two sub-expressions are evaluated before the array access expression itself, in order to evaluate the expression.
After evaluating the two sub-expressions
nada()[index = 2]++;
becomes
null[2]++;
Only now the expression is evaluated and the NullPointerException
is thrown.
This is consistent with the evaluation of most expressions in Java (the only counter examples I can think of are short circuiting operators such as && and ||).
For example, if you make the following method call:
firstMethod().secondMethod(i = 2);
First you evaluate firstMethod()
and i = 2
, and only later you throw NullPointerException
if firstMethod()
evaluated to null
.
This is because in the generated bytecode there are no explicit null checks.
nada()[index = 2]++;
is translated into the following byte code:
// evaluate the array reference expression
INVOKESTATIC Test3.nada ()[I
// evaluate the index expression
ICONST_2
DUP
ISTORE 1
// access the array
// if the array reference expression was null, the IALOAD operation will throw a null pointer exception
DUP2
IALOAD
ICONST_1
IADD
IASTORE
The basic byte code operations are (for an int[]
)
ALOAD array_address
ILOAD index
IALOAD array_element_retrieval
The IALOAD does the null pointer check. In reality the code is a bit more elaborate:
- calculate array address
- calculate index
- IALOAD
So the answer is: it would need an extra checking operation after the array address is loaded, in anticipation of the array access.
Behavior by straight implementation.