Tom*_*ski 4 java-8 functional-interface method-reference
我正在学习Java 8中的方法参考,我很难理解为什么这有效?
class Holder {
private String holded;
public Holder(String holded) {
this.holded = holded;
}
public String getHolded() {
return holded;
}
}
private void run() {
Function<Holder, String> getHolded = Holder::getHolded;
consume(Holder::getHolded); //This is correct...
consume(getHolded); //...but this is not
}
private void consume(Consumer<Holder> consumer) {
consumer.accept(null);
}
Run Code Online (Sandbox Code Playgroud)
正如您在run方法中看到的那样- Holder::getHolded返回未绑定的方法引用,您可以通过将类型的对象Holder作为参数传递来调用它.像这样:getHolded.apply(holder)
但是为什么它将这个未绑定的方法引用转换Consumer为直接作为方法参数调用的时候,并且在我Function明确传递时它不会执行它?
这里有两件事,lambda表达式是poly表达式 - 它们是由编译器使用它们的上下文推断出来的(比如泛型).
当你声明时consume(Holder::getHolded);,编译器(在所谓的特殊无效兼容性规则下)将推断它Consumer<Holder>.
这可能看起来并不明显,但想想一个简化的例子.调用一个方法并丢弃它的返回类型通常不仅仅是好的,对吧?例如:
List<Integer> list = new ArrayList<>();
list.add(1);
Run Code Online (Sandbox Code Playgroud)
即使list.add(1)返回布尔值,我们也不关心它.
因此,您的示例可以简化为:
consume(x -> {
x.getHolded(); // ignore the result here
return;
});
Run Code Online (Sandbox Code Playgroud)
所以这些都是可能的和有效的声明:
Consumer<Holder> consumer = Holder::getHolded;
Function<Holder, String> function = Holder::getHolded;
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,我们明确地告诉了什么类型Holder::getHolded,它不是编译器推断,因此consume(getHolded);失败,a Consumer!= Function毕竟.
| 归档时间: |
|
| 查看次数: |
115 次 |
| 最近记录: |