为什么方法调用参数的拆箱不会导致有用的 NullPointerException

Cla*_*lke 3 java

我研究了 Java 14 中有用的 NullPointerExceptions 并测试了不同的场景。令人惊讶的是,在某些情况下,拆箱似乎会导致有用的 NPE,而其他情况则不包含任何错误消息:

// NPE with message 'Cannot invoke "java.lang.Integer.intValue()" because "index" is null'
Integer index = null;
int i = index;

// NPE with message null
List.of('a', 'b', 'c').indexOf(index);
Run Code Online (Sandbox Code Playgroud)

我想知道为什么第二个例子不会产生与第一个例子相同的消息。我阅读了JEP 358,了解到该消息是根据字节码指令计算的。这两种情况有什么不同吗?我希望两个 snearios 都调用 Integer.intValue() 来取消装箱该值。

(使用 Oracle JDK 17.0.4.1 测试)

Mar*_*eel 7

究其原因,是因为原因不同。创建ListList.of不允许为空,并且当indexOf接收到 a时null,它只是抛出 aNullPointerException而没有消息:

@Override
public int indexOf(Object o) {
    if (!allowNulls && o == null) {
        throw new NullPointerException();
    }
    Object[] es = elements;
    for (int i = 0; i < es.length; i++) {
        if (Objects.equals(o, es[i])) {
            return i;
        }
    }
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

(来自java.util.ImmutableCollections.ListN班级)

另一方面,在 的情况下,int i = index;它被编译为 的等价物int i = index.intValue();,并且 JVMNullPointerException根据所涉及的方法调用和变量生成 的消息。