This question already has an answer here:
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.
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)
).
At line 4 I am
- creating an instance of a class that implements
F
interface - implementing the method by using the reference
one
to invokebar()
method
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"?
Your lambda is compiled into private synthetic method which looks like this:
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:
And call site is technically replaced with constructor call, thus instead of
You effectively have
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.