java - Lambda 表达式 : reference to an instance method of a particular object

标签 java lambda java-8

<分区>

此代码使用对特定对象的实例方法的方法引用:

public class Main {
    public static void main(String[] args) {
        One one=new One();
        // F f = ()->{one.bar();};   //previous wrong syntax
        F f = one::bar;              //4
        f.foo();
    }
}

class One{void bar(){}}
interface F{void foo();}

我知道它有效。但我无法理解为什么如何

我无法理解的是 F.foo() 方法怎么可能使用对对象的引用,而该对象不是方法本身的参数(签名不是 void foo(一一))。

我在第 4 行

  1. 创建实现F 接口(interface)的类的实例
  2. 通过引用one调用bar()方法实现方法

但是 foo() 怎么能在 one 引用上有作用域呢?尝试将此解决方案转换为“传统的、明确的实现”是不是我错了?如果不是,它会是什么“明确对应物”?

最佳答案

您的 lambda 被编译成如下所示的私有(private)合成方法:

private static void lambda$1(One one) { one.bar(); }

在运行时,lambda 表达式会在您第一次执行此代码时转换为运行时表示形式。当前 OpenJDK 8 中的运行时表示是一个匿名类,它将捕获的变量作为构造函数参数并将它们存储到字段中,然后调用编译器生成的 lambda 主体方法。生成了这样的东西:

class lambda12345678 implements F {
    private One arg1;

    lambda12345678(One arg1) {this.arg1 = arg1;}

    public void foo() {
        lambda$1(arg1);
    }
}

并且调用站点在技术上被构造函数调用所取代,因此而不是

F f = ()->{one.bar();};

你实际上有

F f = new lambda12345678(one);

请注意,如果您的 lambda 不捕获上下文,它会以更有效的方式工作:只创建和重用一个对象。但在您的示例中,每次创建新实例时,lambda 行为都取决于外部状态。

关于java - Lambda 表达式 : reference to an instance method of a particular object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33038239/

相关文章:

java - Java 8 中的 Regex-replace-with-function-evaluation 等效于什么?

Java 8 谓词

java - Spring:如何从一个对象中提取数据并将其插入到另一个对象中

c++ - lambda 表达式中的作用域

c# - 具有数据库列名称到实际列值的字符串参数

c# - 如何使用 lambda 表达式来过滤数据行?

java - 将旧循环转换为 Java8 循环

java - 绕过 4GB JAR 限制

java - 服务层的 Spring AOP

java - startActivity() 强制关闭我的应用程序