Java 8:方法引用Bound Receiver和UnBound Receiver之间的区别

Har*_*ara 10 java lambda java-8 method-reference

我试图在我的代码中使用Java 8方法引用.有四种类型的方法参考可用.

  1. 静态方法参考.
  2. 实例方法(绑定接收器).
  3. 实例方法(UnBound接收器).
  4. 构造函数引用.

随着Static method referenceConstructor reference我有没有问题,但Instance Method (Bound receiver)Instance Method (UnBound receiver)真搞糊涂了.在Bound接收器中,我们使用Object引用变量来调用方法,如:

objectRef::Instance Method
Run Code Online (Sandbox Code Playgroud)

UnBound接收器中,我们使用类名来调用方法,如:

ClassName::Instance Method.
Run Code Online (Sandbox Code Playgroud)

我有以下问题:

  1. 实例方法的不同类型的方法引用需要什么?
  2. BoundUnbound接收方法引用有什么区别?
  3. 我们应该Bound在哪里使用Unbound接收器?我们应该在哪里使

我还从Java 8语言特性书中找到了解释BoundUnbound接收器,但仍然与实际概念混淆.

Joh*_*ler 18

unBound接收器的想法String::length就是你指的是一个对象的方法,它将作为lambda的一个参数提供.例如,lambda表达式(String s) -> s.toUpperCase()可以重写为String::toUpperCase.

但是Bounded指的是当你将lambda中的方法调用到已经存在外部对象时的情况.例如,lambda表达式() -> expensiveTransaction.getValue()可以重写为expensiveTransaction::getValue.

三种不同方法参考的情况

(args) -> ClassName.staticMethod(args)ClassName::staticMethod

(arg0, rest) -> arg0.instanceMethod(rest) 可以ClassName::instanceMethod(arg0是类型ClassName)

(args) -> expr.instanceMethod(args)expr::instanceMethod

从Action 8中的Java 8中退出的答案


Jon*_*eet 10

基本上,未绑定的接收器允许您使用实例方法,就好像它们是具有声明类型的第一个参数的静态方法一样 - 因此您可以通过传入您想要的任何实例将它们用作函数.对于绑定接收器,"目标"实例实际上是功能的一部分.

一个例子可能会使这更清楚:

import java.util.function.*;

public class Test {

    private final String name;

    public Test(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        Test t1 = new Test("t1");
        Test t2 = new Test("t2");

        Supplier<String> supplier = t2::method;
        Function<Test, String> function = Test::method;

        // No need to say which instance to call it on -
        // the supplier is bound to t2            
        System.out.println(supplier.get());

        // The function is unbound, so you need to specify
        // which instance to call it on
        System.out.println(function.apply(t1));
        System.out.println(function.apply(t2));
    }

    public String method() {
        return name;
    }
}
Run Code Online (Sandbox Code Playgroud)