ठीक है, लैम्ब्डा भाव संकलन के दौरान तरीकों में desugared कर रहे हैं और जब तक वे this
पर कब्जा नहीं है (उपयोग न कर लें गैर static
सदस्यों में टूट सकता है), ये विधियां static
होगी। मुश्किल तरीका इन विधियों को प्राप्त करना है क्योंकि कार्यात्मक इंटरफ़ेस उदाहरण और इसकी लक्ष्य विधि के बीच कोई निरीक्षण योग्य संबंध नहीं है।
इस सबसे सामान्य स्थिति दर्शाने के लिए, यहाँ:
public class LambdaToMethod {
public static void legacyCaller(Object arg, Method m) {
System.out.println("calling Method \""+m.getName()+"\" reflectively");
try {
m.invoke(null, arg);
} catch(ReflectiveOperationException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) throws URISyntaxException
{
Consumer<String> consumer=s -> System.out.println("lambda called with "+s);
for(Method m: LambdaToMethod.class.getDeclaredMethods())
if(m.isSynthetic() && m.getName().contains("lambda")) {
legacyCaller("a string", m);
break;
}
}
}
यह सुचारू रूप से काम करता है के रूप में वहाँ केवल एक लैम्ब्डा अभिव्यक्ति और इसलिए, एक उम्मीदवार विधि।
static Method lambdaToMethod(Serializable lambda) {
for(Class<?> cl=lambda.getClass(); cl!=null; cl=cl.getSuperclass()) try {
Method m=cl.getDeclaredMethod("writeReplace");
m.setAccessible(true);
try {
SerializedLambda sl=(SerializedLambda)m.invoke(lambda);
return LambdaToMethod.class.getDeclaredMethod(sl.getImplMethodName(),
MethodType.fromMethodDescriptorString(sl.getImplMethodSignature(),
LambdaToMethod.class.getClassLoader()).parameterArray());
} catch(ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
} catch(NoSuchMethodException ex){}
throw new AssertionError();
}
public static void main(String[] args)
{
legacyCaller("a string", lambdaToMethod((Consumer<String>&Serializable)
s -> System.out.println("first lambda called with "+s)));
legacyCaller("a string", lambdaToMethod((Consumer<String>&Serializable)
s -> System.out.println("second lambda called with "+s)));
}
यह काम करता है, तथापि: कि विधि का नाम संकलक विशिष्ट है और कुछ सीरियल नंबर या हैश कोड, हो सकती है आदि
kludge पर लैम्ब्डा अभिव्यक्ति serializable बनाने के लिए और अपने धारावाहिक रूप निरीक्षण करने के लिए है , serializable lambdas एक उच्च कीमत पर आते हैं।
सरल समाधान जब तरीकों से अधिक पुनरावृत्ति पाया जा सकता है लैम्ब्डा अभिव्यक्ति का एक पैरामीटर के लिए टिप्पणी जोड़ने के लिए, हालांकि, वर्तमान में, javac
एनोटेशन ठीक से की दुकान नहीं है, यह भी देखना this question इस बारे में हो सकता है विषय।
लेकिन क्या आप भी विचार कर सकते हैं बस कोड के बजाय एक लैम्ब्डा अभिव्यक्ति पकड़े साधारण static
तरीकों का निर्माण।एक विधि के लिए Method
ऑब्जेक्ट प्राप्त करना सीधे आगे है और आप अभी भी विधि संदर्भों का उपयोग करके उनमें से एक कार्यात्मक इंटरफ़ेस उदाहरण बना सकते हैं ...
लैम्ब्डा अभिव्यक्ति के लिए 'विधि' उदाहरण की तरह कुछ भी नहीं है। लैम्ब्डा अज्ञात कार्यों के लिए वाक्य रचनात्मक चीनी हैं। वे आपको एक उदाहरण देते हैं, लेकिन आप इसे – Jatin
@Jatin से बाहर नहीं कर सकते हैं जाहिर है, संश्लेषित कार्यात्मक इंटरफेस इम्प्लेमेंटेशन अभी भी सामान्य तरीकों के साथ एक सामान्य वस्तु है, जिसे आप सामान्य प्रतिबिंब का उपयोग करने के लिए उपयोग कर सकते हैं। मैं बस सोच रहा हूं कि क्लोजर को लपेटने के तरीके को कैसे प्राप्त किया जाए। –