方法引用表达式评估中空检查背后的原因是什么?

What is the reason behind null checks in method reference expression evaluation?

人们已经意识到使用计算结果为 null 值的表达式创建方法引用将导致 NullPointerException。例如:

String s = null;
Supplier<char[]> fun = s::toCharArray;

这是由于 java 规范中的以下段落:

First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated. If the subexpression evaluates to null, a NullPointerException is raised, and the method reference expression completes abruptly. If the subexpression completes abruptly, the method reference expression completes abruptly for the same reason.

现在我的问题是,有没有人碰巧知道这个(基于许多混淆的问题)违反直觉的规范背后的原因was/is?

我唯一想到的是,在下面的情况下,如果发生在Supplier的评估期间,很难准确报告NullPointerException的错误:

public static char[] callback(Supplier<char[]> supplier) {
    return supplier.get();
}

public static void main(String[] args) {
    String s = null;
    callback(s::toCharArray);
}

这里的原因是当您创建非静态方法引用时,它必须能够访问 this。当您尝试创建对 null 对象的引用时,任何地方都没有 this ,这就是为什么它应该在这一步失败,而不是在第一次使用时在代码中的某个地方失败。

想象一下,您在一个地方获得对象,将其方法引用保存在某处,然后在完全不同的代码部分中使用它。你会得到一个 NPE 不在错误发生的地方,而是在很多代码行之外。

因为 Java 编译器不是 linter/logic 检查器。
Java 中没有任何内容可以阻止您通过取消引用 null.
来触发 NPE 例如 Java 不会阻止你做 :

String s = null;
s.toString();

那是在 Java 8 之前,今天仍然是方法参考。

您引用的段落简单地详细说明了 JVM 如何 在运行时 JVM 处理方法引用的这一点,即如果方法引用评估的一部分失败,则整个评估都会失败。

请注意,在您的实际示例中,您的 IDE 可能会发出警告,因为潜在错误的范围非常小。