Java 8中静态方法引用的限制

Jos*_*one 7 java java-8 method-reference

我正在尝试使用方法引用来捕获方法调用,并且遇到了一些限制.这很好用:

<T> void capture(Function<T, ?> in) {
}

private interface Foo {
  String getBar();
} 

capture(Foo::getBar);
Run Code Online (Sandbox Code Playgroud)

但是,如果我将Foo.setBar的签名更改为以下内容:

private interface Foo {
  void setBar(String bar);
}

capture(Foo::setBar);
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

Cannot make a static reference to the non-static method setBar(String) from the type MyTest.Foo

我不清楚限制是什么.理想情况下,我想使用方法引用来捕获标准setter上的调用.有没有办法做到这一点?

Jon*_*eet 13

这里有两个问题:

  • 你正在使用Function,必须返回一些东西.setBar没有任何回报.
  • Function只需要一个输入,但你有两个输入:Foo你要调用setBar的,以及String你传入的参数setBar.

如果改为使用BiConsumer(具有void返回类型和两个输入),它可以正常工作:

static <T, U> void capture(BiConsumer<T, U> in) {
}
Run Code Online (Sandbox Code Playgroud)

您可以重载您的capture方法以具有两个签名:

static <T, U> void capture(BiConsumer<T, U> in) { }
static <T> void capture(Function<T, ?> in) { }
Run Code Online (Sandbox Code Playgroud)

然后使用两个方法引用:

capture(Foo::setBar);
capture(Foo::getBar);
Run Code Online (Sandbox Code Playgroud)


nos*_*sid 8

Foo::getBar对应于获取Foo(目标对象)并返回a 的函数String.该接口Function<Foo, String>可用于表示这样的功能.

另一方面,Foo::setBar对应于带有两个参数的函数,a Foo(目标对象)和String(第一个参数).匹配的界面是BiConsumer<Foo, String>.这意味着你需要一个重载BiConsumer:

<T, U> void capture(BiConsumer<T, U> setter) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)