Lambda表达式:引用特定对象的实例方法 [英] Lambda expressions: reference to an instance method of a particular object
问题描述
此代码使用对特定对象的实例方法的方法引用:
This code uses method reference to an instance method of a particular object:
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();}
我知道它有效。但是我无法理解为什么和如何。
I know it works. But I'm not being able to understand why and how.
我无法理解的是是否有可能 F.foo()
方法正在使用对不是方法本身参数的对象的引用(签名不是 void foo(一个)
)。
What I can't understand is how is it possible that F.foo()
method is using a reference to an object that is not an argument to the method itself (signature is not void foo(One one)
).
在第4行我
- 创建一个实现的类的实例
F
interface - 通过使用引用
one
来调用<实现该方法code> bar()方法
- creating an instance of a class that implements
F
interface - implementing the method by using the reference
one
to invokebar()
method
但 foo怎么样( )
在一个
参考上有一个范围?我是否错误地试图将此解决方案转换为传统的,明确的实现?如果没有,那么明确的对应物是什么?
But how can foo()
have a scope on one
reference? Am I being wrong trying to translate this solution to a "traditional, explicit implementation"? If not, what would it be the "explicit counterpart"?
推荐答案
你的lambda被编译成私有的合成方法,看起来像这样:
Your lambda is compiled into private synthetic method which looks like this:
private static void lambda$1(One one) { one.bar(); }
在运行时,lambda表达式在您第一次执行此代码时被转换为运行时表示形式。 OpenJDK 8中的当前运行时表示是一个匿名类,它将捕获的变量作为构造函数参数并将它们存储到字段中,然后调用由编译器生成的lambda body方法。生成这样的东西:
At runtime the lambda expression is translated into runtime representation during the first time you execute this code. Current runtime representation in OpenJDK 8 is an anonymous class which takes the captured variables as constructor parameters and stores them into fields, then calls the lambda body method generated by compiler. Something like this is generated:
class lambda12345678 implements F {
private One arg1;
lambda12345678(One arg1) {this.arg1 = arg1;}
public void foo() {
lambda$1(arg1);
}
}
并且呼叫站点在技术上被构造函数调用替换,因此而不是
And call site is technically replaced with constructor call, thus instead of
F f = ()->{one.bar();};
您实际拥有
F f = new lambda12345678(one);
请注意,如果你的lambda不捕获上下文,它的工作方式更有效:只有一个对象是创建并重用。但是在你的例子中,lambda行为依赖于外部状态,每次创建新实例时。
Note that if your lambda does not capture context, it works in more efficient way: only one object is created and reused. But in your example as lambda behavior depends on external state, every time the new instance is created.
这篇关于Lambda表达式:引用特定对象的实例方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!