获取lambdas类的列表 [英] Get a list of classes lambdas

查看:71
本文介绍了获取lambdas类的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java 8中,看起来类的lambda保存在数组中。例如,假设我们有这个类:

In Java 8 it looks like the lambdas of a class are kept in an array. For example, lets say we have this class:

public class LambdaFactory {
    public Supplier<Integer> getOne(){
        return () -> 42;
    }

    public Supplier<Integer> getTwo(){
        return () -> 128;
    }

    public Supplier<Integer> getThree(){
         return () -> 3;
    }
}

然后我这样打印出来:

    System.out.println(factory.getOne());
    System.out.println(factory.getOne());
    System.out.println(factory.getTwo());
    System.out.println(factory.getThree());

输出类似于

examples.LambdaFactory$$Lambda$1@4e515669
examples.LambdaFactory$$Lambda$1@4e515669
examples.LambdaFactory$$Lambda$2@1b9e1916
examples.LambdaFactory$$Lambda$3@ba8a1dc

所以我们在这里可以看到两件事。调用两次的同一个lambda给了我们相同的lambda对象(这与我们每次都可以得到一个新的内部类不同)。我们也看到他们看起来像是被保留在某种Lambda结构中,而这种结构是该类的一部分

So we can see two thing here. The same lambda called twice gives us the same lambda object (this is not the same as with anon inner classes where we could get a new one every time). We also see that they look like they are being kept in some kind of "Lambda" structure that is part of the class

我的问题是,我可以得到它吗?班里的羔羊?我没有任何理由这样做,我只是喜欢解剖一切

My question is, can I get ahold of the lambdas in a class? I don't have any reason to do so, I just like dissecting things

推荐答案

lambdas是由JRE创建的它们的创建方式由JRE控制,可能因JRE供应商而异,并且可能会在未来版本中发生变化。

The lambdas are created by the JRE and the way they are created is controlled by the JRE and might vary between different JRE vendors and might change in future versions.

如果你想获得乐趣,你可以创建一个lambda运行时在类文件中没有相应的信息:

If you want to have fun you can create a lambda at runtime which has no corresponding information within the class file:

import java.lang.invoke.*;

public class ManualLambda {
  public static void main(String[] args) throws Throwable {
    MethodHandles.Lookup me=MethodHandles.lookup();
    MethodType t=MethodType.methodType(void.class);
    MethodType rt=MethodType.methodType(Runnable.class);
    CallSite site = LambdaMetafactory.metafactory(
      me, "run", rt, t, me.findStatic(ManualLambda.class, "sayHello", t), t);
    MethodHandle factory=site.getTarget();
    Runnable r=(Runnable)factory.invoke();

    System.out.println("created lambda: "+r);
    r.run();
  }
  private static void sayHello() {
      System.out.println("hello world");
  }
}

上面的代码回顾了创建lambda时会发生什么。但对于编译时(实际)lambda表达式,整个事情由单个 invokedynamic 字节代码指令触发。 LambdaMetafactory.metafactory(...)方法是 bootstrap 方法,当 invokedynamic 指令第一次执行。返回的 CallSite 对象与 invokedynamic 指令永久关联。如果 CallSite ConstantCallSite 并且其 MethodHandle 返回每次执行时都有相同的lambda对象, invokedynamic 指令将永远生成相同的lambda实例。

The code above retraces what happens when a lambda is created. But for compile-time ("real") lambda expressions the entire thing is triggered by a single invokedynamic byte code instruction. The LambdaMetafactory.metafactory(…) method is the bootstrap method which is called when the invokedynamic instruction is executed the first time. The returned CallSite object is permanently associated with the invokedynamic instruction. If the CallSite is a ConstantCallSite and its MethodHandle returns the same lambda object on every execution, the invokedynamic instruction will "produce" the same lambda instance forever.

这篇关于获取lambdas类的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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