Lambda表达式:引用特定对象的实例方法 [英] Lambda expressions: reference to an instance method of a particular object

查看:518
本文介绍了Lambda表达式:引用特定对象的实例方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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行我


  1. 创建一个实现的类的实例 F interface

  2. 通过使用引用 one 来调用<实现该方法code> bar()方法

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆