Lambda表达式与方法参考实现细节 [英] Lambda expression vs method reference implementation details

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

问题描述

鉴于此:

class MyClass {
    static class A {
        public boolean property() {
            return Math.random() < 0.5;
        }
    }

    static List<A> filterLambda(List<A> list) {
        return list.stream().filter(a -> a.property()).collect(Collectors.toList());
    }

    static List<A> filterMethodCall(List<A> list) {
        return list.stream().filter(A::property).collect(Collectors.toList());
    }
}




  • 有什么区别在每个方法的编译器做什么

  • 如果有的话,内存使用情况或运行时间是否存在差异? (即使它很小,问题只是学术问题)

  • PD:我知道问题类似于这个但我认为它没有得到正确解决。

    PD: I know the question is similar to this one but I think it's not been addressed correctly.

    推荐答案

    这是 Brian Goetz的文档由Brett Oken链接:

    This is an extract from the Brian Goetz's doc linked by Brett Oken:


    当编译器遇到lambda表达式时,它首先降低
    (desugars)将lambda体转换为方法
    ,其参数列表和
    返回类型与lambda表达式匹配,可能还有一些
    附加参数(对于从词法中捕获的值)范围,如果
    any。)在捕获lambda表达式时,
    它会生成一个invokedynamic调用站点,当调用它时,返回
    lambda被转换为
    的函数接口的实例。对于给定的
    lambda,此调用站点称为lambda工厂。 lambda工厂的动态参数是从词法范围中捕获的值
    。 lambda
    工厂的bootstrap方法是Java语言运行时库中的标准化方法,
    称为lambda metafactory。静态引导参数在编译时捕获已知有关lambda的
    信息(将转换为它的函数
    接口,
    desugared lambda体的方法句柄,有关SAM是否有关的信息类型是
    serializable等。)

    When the compiler encounters a lambda expression, it first lowers (desugars) the lambda body into a method whose argument list and return type match that of the lambda expression, possibly with some additional arguments (for values captured from the lexical scope, if any.) At the point at which the lambda expression would be captured, it generates an invokedynamic call site, which, when invoked, returns an instance of the functional interface to which the lambda is being converted. This call site is called the lambda factory for a given lambda. The dynamic arguments to the lambda factory are the values captured from the lexical scope. The bootstrap method of the lambda factory is a standardized method in the Java language runtime library, called the lambda metafactory. The static bootstrap arguments capture information known about the lambda at compile time (the functional interface to which it will be converted, a method handle for the desugared lambda body, information about whether the SAM type is serializable, etc.)

    方法引用的处理方式与lambda表达式相同,
    除了大多数方法引用都做不需要被贬低为
    新方法
    ;我们可以简单地为
    引用的方法加载一个常量方法句柄并将其传递给metafactory。

    Method references are treated the same way as lambda expressions, except that most method references do not need to be desugared into a new method; we can simply load a constant method handle for the referenced method and pass that to the metafactory.

    从中提取的示例doc:

    Examples extracted from same doc:

    例如,考虑一个捕获字段minSize的lambda:

    As an example, consider a lambda that captures a field minSize:

    list.filter(e -> e.getSize() < minSize )
    

    我们将此作为一个实例方法,并将接收器作为第一个捕获的参数传递:

    We desugar this as an instance method, and pass the receiver as the first captured argument:

    list.forEach(INDY((MH(metaFactory), MH(invokeVirtual Predicate.apply),
                        MH(invokeVirtual B.lambda$1))( this ))));
    
    private boolean lambda$1(Element e) {
        return e.getSize() < minSize; }
    

    虽然

    list.filter(String::isEmpty)
    

    翻译为:

    list.filter(indy(MH(metaFactory), MH(invokeVirtual Predicate.apply),
                 MH(invokeVirtual String.isEmpty))()))
    

    这篇关于Lambda表达式与方法参考实现细节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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