Java 8中静态方法引用的限制
我正在尝试使用方法引用来捕获方法调用,并且遇到了一些限制。 这很好用:
void capture(Function in) { } private interface Foo { String getBar(); } capture(Foo::getBar);
但是,如果我将Foo.setBar的签名更改为以下内容:
private interface Foo { void setBar(String bar); } capture(Foo::setBar);
我收到一个错误:
Cannot make a static reference to the non-static method setBar(String) from the type MyTest.Foo
我不清楚限制是什么。 理想情况下,我想使用方法引用来捕获标准setter上的调用。 有没有办法做到这一点?
这里有两个问题:
- 你正在使用
Function
,它必须返回一些东西。setBar
不返回任何内容。 -
Function
只接受一个输入,但是你有两个输入:你要调用setBar
的Foo
,以及你传递给setBar
的String
参数。
如果您改为使用BiConsumer
(它具有void
返回类型和两个输入),它可以正常工作:
static void capture(BiConsumer in) { }
您可以重载capture
方法以具有两个签名:
static void capture(BiConsumer in) { } static void capture(Function in) { }
然后使用两个方法引用:
capture(Foo::setBar); capture(Foo::getBar);
Foo::getBar
对应于一个接受Foo
(目标对象)并返回String
的函数。 接口Function
可用于表示此类函数。
另一方面, Foo::setBar
对应于一个带有两个参数的函数,一个是Foo
(目标对象),另一个是String
(第一个参数)。 匹配的接口是BiConsumer
。 这意味着你需要BiConsumer
的重载:
void capture(BiConsumer setter) { // ... }
暴露语法糖方法参考,你应该看到,那
Foo::getBar
等于
(Foo)foo -> foo.getBar()
这是Function
但
Foo::setBar
在这个上下文中是两个变量的函数( foo
和一些String str
),所以它不是一个变量的函数( Function
)
为了更方便的答案,您应该看到允许方法引用的位置:
- 引用静态方法(根本不是这种情况)
- 引用特定对象的实例方法(根本不是这种情况)
-
引用特定类型的任意对象的实例方法(本例)
在上面的说明中有一个例子,几乎与你的情况相同。 据说,等效的lambda表达式将采用两个参数(在本例中为
Foo
和String
),这不是Function
-
引用构造函数(根本不是这种情况)