是否可以在运行时检索lambda表达式

Xav*_*lon 7 java lambda bytecode java-8

我昨晚玩Java8 Lambda,我想知道是否可以在运行时检索Lambda表达式.简而言之,据我所知,Lambda表达式在运行时转换为(静态)方法,然后使用InvokeDynamics调用.

我们举个这样的例子:

people.filter(person -> person.getAge() >= minAge);
Run Code Online (Sandbox Code Playgroud)

filter将a Predicate<T>作为参数的自定义方法在哪里.在这个filter方法中,如何person -> person.getAge() >= minAge在这种情况下以与Lambda表达式()相似(或相同)的形式检索参数?

我尝试使用ASM5_BETA读取参数类的生成字节码,但我无法使用ClassVisitor和MethodVisitor来访问与Lambda表达式相关联的方法.

public <T> List<T> filter(Filter<T> expression) {
    try {
        Class<? extends Filter> expressionClass = expression.getClass();
        byte[] content = getClassContent(expressionClass);
        ClassReader classReader = new ClassReader(content);
        classReader.accept(new PredicateClassVisitor(), 0);
    } catch (Throwable e) {
        e.printStackTrace();
    }
    return null;
}

private byte[] getClassContent(Class<? extends Filter> expressionClazz) throws  
               IOException {
    InputStream stream = Thread.currentThread().getContextClassLoader()
                           .getResourceAsStream(getClassName(expressionClazz.getName()));
    return IOUtils.toByteArray(stream);
}

private String getClassName(String expressionClazz) {
    return expressionClazz.substring(0, expressionClazz.indexOf('$'))
           .replace('.', '/') + ".class";
}

static class PredicateClassVisitor extends ClassVisitor {

    public PredicateClassVisitor() {
        super(Opcodes.ASM4);
    }

    @Override
    public MethodVisitor visitMethod(int i, String s, String s2, String s3, 
                                     String[] strings) {
        return new PredicateMethodVisitor();
    }
}

static class PredicateMethodVisitor extends MethodVisitor {

    public PredicateMethodVisitor() {
        super(Opcodes.ASM4);
    }

    @Override
    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
                                       Object... bsmArgs) {
        for (Object object : bsmArgs) {
              System.out.println(" " + object.toString());
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

我不确定这是否是正确的道路,我想知道ASM或JDK8中是否有更合适的工具用于此目的.

感谢您的任何建议;-)最好的问候,泽维尔

Hol*_*ger 5

你已经知道 lambda 表达式通常被编译成一个合成方法,所以你已经知道要反编译哪些代码来获得 lambda 的源代码,或者,类似于原始代码的东西,甚至看起来完全不同的东西,取决于特定的代码.

没有理由反编译 lambda 表达式比反编译任何其他 Java 表达式更容易。简单的表达式可能很容易恢复,特别是当代码有调试信息时,复杂的表达式在反编译时很可能看起来不同,尤其是当编译器对代码应用优化时。