Why doesn't an array access expression of a null array reference throw a NullPointerException?

混江龙づ霸主 提交于 2019-12-22 06:36:07

问题


Consider the following code:

int[] r = null;
r[0] = 1 % 0;

I would have expected this to throw a NullPointerException: according to JLS Sec 15.7.1:

The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.

= is a binary operator (shown in JLS Sec 15.2 - JLS Sec 15.26 describes assignment operators), and fully-evaluating the left-hand operand will result in a NullPointerException. However, an ArithmeticException is thrown, indicating that the right-hand operand is evaluated before the left-hand operand is fully evaluated.

Why?


回答1:


The specification of the simple assignment operator describes this behavior:

...

If the left-hand operand is an array access expression (§15.10.3), possibly enclosed in one or more pairs of parentheses, then:

  • First, the array reference subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the index subexpression (of the left-hand operand array access expression) and the right-hand operand are not evaluated and no assignment occurs.

This completes normally.

  • Otherwise, the index subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and the right-hand operand is not evaluated and no assignment occurs.

This completes normally.

  • Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

This completes abruptly, with ArithmeticException.

  • Otherwise, if the value of the array reference subexpression is null, then no assignment occurs and a NullPointerException is thrown.

This is never executed.

So, it appears that there is inconsistency - or over-simplification, at least - in the quote from Sec 15.7.1.


Interestingly, the same behavior is not observed for the compound assignment operators, e.g.

int[] arr = null;
arr[0] += 1 % 0;

does yield a NullPointerException.

JLS Sec 15.26.2 describes this. It's perhaps less surprising, though, because:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

In other words, this code is (roughly) equivalent to:

arr[0] = arr[0] + 1 % 0;

so the NullPointerException occurs in evaluating the right hand operand of the simple assignment.



来源:https://stackoverflow.com/questions/42854455/why-doesnt-an-array-access-expression-of-a-null-array-reference-throw-a-nullpoi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!