昨晚我在玩Java8 Lambda,並且想知道是否可以在運行時檢索Lambda表達式。總之,據我所知,Lambda表達式在運行時轉換爲(靜態)方法,然後使用InvokeDynamics調用。是否有可能在運行時檢索lambda表達式
讓我們這樣一個例子:
people.filter(person -> person.getAge() >= minAge);
其中filter
將採取Predicate<T>
作爲參數的自定義方法。 在這個filter
方法中,我如何在這種情況下以類似於(或相同)的Lambda表達式(person -> person.getAge() >= minAge
)的形式檢索參數?
我嘗試使用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());
}
}
}
我不知道這是遵循了正確的道路,我想知道是否有在ASM或JDK8更合適的工具用於這一目的。
感謝您的任何意見;-) 最好的問候, 澤維爾
你究竟想在這裏實現什麼?在你解釋這個之前,很難告訴你。 –
通過「檢索lambda表達式」我把它你的意思是「生成」。順便說一下,lambda調用本身並沒有超過InvokeDynamic,這僅用於創建lambda invocator對象的過程中。 –
我想要捕獲調用代碼中提供的Lambda表達式,例如爲了日誌記錄目的或其他用法,也許。我不是在談論生成字節碼而是在生成JVM。從上面給出的例子中,在'filter(Filter expression)'方法中,我希望能夠將給定的'expression'參數恢復爲'person - > person.getAge()> = minAge' lambda表達。這是可行的嗎? –