此代码使用对特定对象的实例方法的方法引用:
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();}
我知道它有效。但我无法理解why and how.
我不明白的是怎么可能F.foo()
方法使用对对象的引用,该对象不是方法本身的参数(签名不是void foo(One one)
).
在第 4 行我是
- 创建一个实现类的实例
F
界面
- 使用参考实现该方法
one
调用bar()
method
但怎样才能foo()
有一个范围one
参考?我试图将此解决方案转化为“传统的、显式的实现”是错误的吗?如果不是,那么“显式对应”是什么?
你的 lambda 被编译成私有合成方法,如下所示:
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 行为都取决于外部状态。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)