पर लैम्ब्डा अभिव्यक्ति को पुनर्प्राप्त करना संभव है, मैं कल रात जावा 8 लैम्ब्डा के साथ खेल रहा था और मैं सोच रहा था कि रनटाइम पर लैम्ब्डा अभिव्यक्ति को पुनर्प्राप्त करना संभव है या नहीं। संक्षेप में और जहां तक मुझे समझा गया, लैम्ब्डा अभिव्यक्ति को रनटाइम पर (स्थैतिक) विधियों में परिवर्तित कर दिया गया और फिर InvokeDynamics का उपयोग करने के लिए कहा जाता है।रनटाइम
के इस तरह एक उदाहरण लेते हैं:
people.filter(person -> person.getAge() >= minAge);
जहां filter
एक Predicate<T>
एक पैरामीटर के रूप लेने के लिए एक कस्टम तरीका होगा। इस filter
विधि के अंदर, मैं इस मामले में लैम्ब्डा अभिव्यक्ति (person -> person.getAge() >= minAge
) के समान (या समान) रूप में तर्क को कैसे प्राप्त कर सकता हूं?
मैंने एएसएम 5_BETA का उपयोग करके तर्क वर्ग के उत्पन्न बाइटकोड को पढ़ने की कोशिश की लेकिन मैं लैम्बडा अभिव्यक्ति से जुड़े विधि तक पहुंचने के लिए क्लासविजिटर और विधिविज्ञानी का उपयोग करने से आगे नहीं जा सका।
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());
}
}
}
मुझे यकीन है कि यह सही मार्ग का अनुसरण करने के लिए है नहीं कर रहा हूँ, और अगर वहाँ इस तरह के एक उद्देश्य के लिए एएसएम में या JDK8 में अधिक उपयुक्त टूलींग थे मैं सोच रहा था।
किसी भी सलाह ;-) सादर, जेवियर
आप वास्तव में यहां प्राप्त करने की कोशिश कर रहे हैं? जब तक आप इसे समझा नहीं देते, आपको सलाह देना मुश्किल होता है। –
"लैम्ब्डा अभिव्यक्ति पुनर्प्राप्त करें" द्वारा मैं इसे "उत्पन्न" का मतलब लेता हूं। बीटीडब्ल्यू लैम्बडा कॉल स्वयं InvokeDynamic पर नहीं है, इसका उपयोग केवल लैम्ब्डा इनवोकेटर ऑब्जेक्ट बनाने की प्रक्रिया में किया जाता है। –
मैं लम्बा अभिव्यक्ति को कैप्चर करना चाहता हूं जो कॉलिंग कोड में प्रदान किया गया था, उदाहरण के लिए लॉगिंग उद्देश्य के लिए, या बाद में अन्य उपयोग, शायद। मैं JVM के बजाय बाइटकोड उत्पन्न करने के बारे में बात नहीं कर रहा हूं। ऊपर दिए गए उदाहरण से, 'फ़िल्टर (फ़िल्टर अभिव्यक्ति)' विधि में, मैं दिए गए 'अभिव्यक्ति' को 'व्यक्ति -> person.getAge()> = minAge' lambda पर वापस लाने के लिए सक्षम होना चाहता हूं अभिव्यक्ति। क्या यह करने योग्य है? –