我遇到了一个相当奇怪的编译器行为:可以从静态上下文中引用非静态方法,但并非总是如此。我的理解是
void method() {}
和
void static method(ThisClassName c) {}
应该在JVM中具有相同的签名,因此它们的引用应该具有相同的行为,但是显然我错了。
这是我的示例:
上级:
package com.example;
abstract class Parent<S> {
abstract void doSomething(final S s);
}
儿童:
package com.example;
import java.util.function.BiConsumer;
class Child extends Parent<String> {
// This line compiles OK
private static BiConsumer<Child, String> consumer1 = Child::doSomething;
// Compiler error: "Non-static method cannot be referenced from a static context."
private static BiConsumer<Parent, String> consumer2 = Child::doSomething;
// This line compiles OK
private static BiConsumer<Parent, String> consumer3 = Child::doSomethingElse;
@Override
void doSomething(final String s) {
// do something
}
static void doSomethingElse(final Parent<String> c, final String s) {
// do something else
}
}
这里的问题是由于编译器错误而无法设置consumer2。
我如何遇到这个问题:我需要通过
Map<String, BiConsumer<Parent, ?>>
左右,地图本身仅创建一次(在启动时),因此使其成为静态最终值是有意义的。
这看起来像是编译器错误报告不佳的情况。使用我的编译器(Eclipse),我得到了以下错误:
Child类型未定义适用于此处的doSomething(Parent,String)
确实没有,因为实例方法具有隐式的接收器参数(this
),该参数Child::doSomething
的类型为Child
,因此BiConsumer<Parent, String>
不是兼容的目标类型。
您可以使用对Parent
的版本的引用doSomething
:
private static BiConsumer<Parent, String> consumer2 = Parent::doSomething;
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句