I played with Java8 Lambda yesterday, and I was wondering if it is possible to get a Lambda expression at runtime. In short, as I understand it, a Lambda expression is converted to (static) methods at runtime, and then called using InvokeDynamics.
Take this example:
people.filter(person -> person.getAge() >= minAge);
where filter will be the usual method taking Predicate<T> as a parameter. Inside this filter method, how could I get an argument in a form similar (or identical) to the Lambda expression ( person -> person.getAge() >= minAge ) in this case?
I tried to read the generated bytecode of the argument class using ASM5_BETA, but I couldn't go further than using ClassVisitor and MethodVisitor to get the method associated with the Lambda expression.
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()); } } }
Iām not sure if this is the right way, and I wondered if the ASM or JDK8 had more suitable equipment for this purpose.
Thanks for any advice ;-) Best regards, Xavier
source share