【问题标题】:Creating a method reference on a null-reference does not throw an exception在空引用上创建方法引用不会引发异常
【发布时间】:2016-06-07 14:04:26
【问题描述】:

有什么理由可以在一个对象上创建方法引用 null Java 中的引用?这样做可能永远不会正确,但可能会导致以后难以发现的错误:

public class Test {
    void m() {
    }

    public static void main(String[] args) {
        Test test = null;
        Runnable fn = test::m; // no exception
        System.out.println(fn); // prints Test$$Lambda$1/791452441@1c20c684
        fn.run(); // throws a null pointer exception
    }
}

【问题讨论】:

  • 您正在使用 Eclipse 进行测试吗?我用 JDK 1.8.0_51 进行了测试,它在预期的地方抛出了 NPE。这可能回答了stackoverflow.com/questions/37413106/… 的问题。因为它应该在Runnable fn = test::m 处抛出一个 NPE。
  • @Michael 是的,Eclipse 中似乎存在一个与此相关的错误(与链接问题相同)。
  • Eclipse Neon 中仍然存在问题
  • 当你的工具这样误导你时,这很痛苦。
  • 有点意思,因为对于这种类型的方法引用,:: 的左边是一个返回引用的表达式。虽然这更明确地是一个空引用,但这将具有相同的效果:functionThatReturnsNull()::method

标签: java eclipse nullpointerexception null java-8


【解决方案1】:

为什么可以在 Java 中的 null 引用上创建方法引用?

不是,但显然 Eclipse 在这方面存在错误(编辑:自 been fixed 以来一直存在)。根据规范,当您使用 JDK 的工具时,它会在 Runnable fn = test::m; 行出现 NPE 失败。

证明:http://ideone.com/APWXna(或者使用javacjava而不是Eclipse在本地编译和运行)

理论:来自JLS §15.13.3

首先,如果方法引用表达式以 ExpressionNamePrimary 开头,则计算此子表达式。 如果子表达式的计算结果为null,则会引发NullPointerException,并且方法引用表达式会突然完成。

(我的重点。)

【讨论】:

  • 此错误是否已报告给 Eclipse?
  • @DidierL:我不知道,我不使用 Eclipse。
  • 作为一种解决方法:如果您仍然想使用可为空对象的方法,则不会在评估阶段抛出 Lambda 或静态方法引用。 [可运行 fn = () -> test.m()] 或 [Consumer c2 = Test ::m]
猜你喜欢
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多