使用 null 参数调用对任意对象的方法引用时出现 NullPointerException
NullPointerException when calling a method reference to an arbitrary object with null argument
我试图创建一个对任意对象的方法引用,所以我定义了以下类型:
interface I {
boolean get(Impl impl);
}
static class Impl {
public boolean get() {
return true;
}
}
然后我声明了方法引用,如下所示:
I i = Impl::get;
当我打电话时:
i.get(null);
我收到 NullPointerException:
Exception in thread "main" java.lang.NullPointerException
有人可以解释为什么即使 Impl
引用没有在任何地方使用也会发生这种情况吗?
我想你误解了这行的意思:
I i = Impl::get;
I
是一个函数式接口,代表一个接受 Impl
和 returns 一个 boolean
的方法,而 get
是一个接受没有参数和 returns 一个 boolean
。这种转换是如何进行的?嗯,编译器意识到 get
是一个 instance 方法,要调用它你必须需要一个 Impl
对象。这不就像一个函数在调用之前有一个参数吗?
因此编译器可以愉快地推断出您的意思:
I i = impl -> impl.get();
现在NPE的原因应该清楚了。
通常,所有实例方法都可以被认为是带有一个额外参数的静态方法,类型为 T
,其中 T
是该实例方法的声明类型。
我试图创建一个对任意对象的方法引用,所以我定义了以下类型:
interface I {
boolean get(Impl impl);
}
static class Impl {
public boolean get() {
return true;
}
}
然后我声明了方法引用,如下所示:
I i = Impl::get;
当我打电话时:
i.get(null);
我收到 NullPointerException:
Exception in thread "main" java.lang.NullPointerException
有人可以解释为什么即使 Impl
引用没有在任何地方使用也会发生这种情况吗?
我想你误解了这行的意思:
I i = Impl::get;
I
是一个函数式接口,代表一个接受 Impl
和 returns 一个 boolean
的方法,而 get
是一个接受没有参数和 returns 一个 boolean
。这种转换是如何进行的?嗯,编译器意识到 get
是一个 instance 方法,要调用它你必须需要一个 Impl
对象。这不就像一个函数在调用之前有一个参数吗?
因此编译器可以愉快地推断出您的意思:
I i = impl -> impl.get();
现在NPE的原因应该清楚了。
通常,所有实例方法都可以被认为是带有一个额外参数的静态方法,类型为 T
,其中 T
是该实例方法的声明类型。