Eh, lambda ifadeleri derleme sırasında yöntemlerine şekeri alınmış ve yeter ki this
yakalamak yok gibi (erişmezseniz olmayan static
üyelerin bozulabilir), bu yöntemler static
olacaktır. Zor olan bölüm, fonksiyonel arayüz örneği ve hedef yöntemi arasında denetlenebilir bir bağlantı olmadığı için bu yöntemlere ulaşmaktır.
burada, en basit durumda bu göstermek için: Yalnızca bir lambda ifadesi ve dolayısıyla tek aday yöntemi olmadığı için
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;
}
}
}
Bu sorunsuz çalışır. Bununla birlikte, bu işleri
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)));
}
: bu yöntem adı derleyici spesifiktir ve bazı seri numaraları veya karma kodlarını içerebilir vb kludge üzerinde
lambda ifade seri hale ve seri formu kontrol etmektir , seri hale getirilebilir lambdalar yüksek bir fiyata geliyor.
basit çözüm, bununla birlikte, şu anda, javac
doğru ek açıklama depolamaz, yöntemlerine göre ilerlerken bulunabilir lambda ifade parametreye bir ek açıklama da bu konuda this question görmek olacaktır konu.
Ama aynı zamanda dikkate alabilir sadece kodu yerine lambda ifadesi tutan sıradan static
calışmalarımız.Bir yöntem için Method
nesnesinin alınması, düz-ileriye doğrudur ve yöntem referanslarını kullanarak bunların dışında bir işlevsel arabirim örneği oluşturabilirsiniz.
Bir lambda ifadesi için bir "Yöntem" örneği gibi bir şey yoktur. Lambda, anonim işlevler için sözdizimsel şekerdir. Size bir örnek verir, ancak bir yöntem yapamazsınız. – Jatin
@Jatin Açıkçası, sentezlenmiş fonksiyonel arabirim impelementasyonu hala normal yöntemlerle normal bir nesnedir ve normal yansıma erişimini kullanabilirsiniz. Ben sadece klousürün nasıl sarılacağını merak ediyorum. –