Lambda expressions: reference to an instance metho

2019-05-17 05:08发布

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

  1. creating an instance of a class that implements F interface
  2. implementing the method by using the reference one to invoke bar() 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"?

1条回答
一纸荒年 Trace。
2楼-- · 2019-05-17 05:30

Your lambda is compiled into private synthetic method which looks like this:

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

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();};

You effectively have

F f = new lambda12345678(one);

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.

查看更多
登录 后发表回答