Açıkça LambdaMetafactory.metafactory kullanmaya çalışıyorum, neden sadece Runnable işlevsel arabirimiyle çalıştığını anlayamıyorum. Böyle Tedarikçi gibi farklı bir fonksiyonel bir arayüz kullanmaya çalıştığınızdaAçıkça kullanımı LambdaMetafactory
public class MetafactoryTest {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodType methodType = MethodType.methodType(void.class);
MethodType invokedType = MethodType.methodType(Runnable.class);
CallSite site = LambdaMetafactory.metafactory(caller,
"run",
invokedType,
methodType,
caller.findStatic(MetafactoryTest.class, "print", methodType),
methodType);
MethodHandle factory = site.getTarget();
Runnable r = (Runnable) factory.invoke();
r.run();
}
private static void print() {
System.out.println("hello world");
}
}
sorun ortaya çıkar: Örnek için bu kod (Bu "merhaba dünya" yazdırır) ne beklendiğini yapar. Aşağıdaki kod çalışmaz:
public class MetafactoryTest {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodType methodType = MethodType.methodType(String.class);
MethodType invokedType = MethodType.methodType(Supplier.class);
CallSite site = LambdaMetafactory.metafactory(caller,
"get",
invokedType,
methodType,
caller.findStatic(MetafactoryTest.class, "print", methodType),
methodType);
MethodHandle factory = site.getTarget();
Supplier<String> r = (Supplier<String>) factory.invoke();
System.out.println(r.get());
}
private static String print() {
return "hello world";
}
}
Exception in thread "main" java.lang.AbstractMethodError: metafactorytest.MetafactoryTest$$Lambda$1/258952499.get()Ljava/lang/Object;
at metafactorytest.MetafactoryTest.main(MetafactoryTest.java:29)
olmamalı kodun ikinci ön bilgide sorundur benzer şekilde, kod işin iki pasajı?
Ayrıca aşağıdaki kod, bu eşdeğer olmalıdır, iyi çalışır:
public class MetafactoryTest {
public static void main(String[] args) throws Throwable {
Supplier<String> r = (Supplier<String>)() -> print();
System.out.println(r.get());
}
private static String print() {
return "hello world";
}
}
Düzen
yöntem dönüş türü yeni bir fonksiyonel bir arayüz tanımlamaktır değiştirmek önler Başka bir çözüm:
public class MetafactoryTest {
@FunctionalInterface
public interface Test {
String getString();
}
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodType methodType = MethodType.methodType(String.class);
MethodType invokedType = MethodType.methodType(Test.class);
CallSite site = LambdaMetafactory.metafactory(caller,
"getString",
invokedType,
methodType,
caller.findStatic(MetafactoryTest.class, "print", methodType),
methodType);
MethodHandle factory = site.getTarget();
Test r = (Test) factory.invoke();
System.out.println(r.getString());
}
private static String print() {
return "hello world";
}
Belki de sorun, ikinci argüman olarak geçtiğiniz "run" yöntem adıyla ilgilidir. Runnable bir "run" yöntemine sahiptir. Tedarikçi yok. – Eran
Bu bir hataydı (Runnable durumu yalnızca "run" ile çalışır), ancak ikinci snippet'i de bu hataya sahip olsun. – andrebask