方法引用表达式评估中空检查背后的原因是什么?
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 可能会发出警告,因为潜在错误的范围非常小。
人们已经意识到使用计算结果为 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 可能会发出警告,因为潜在错误的范围非常小。