I have a simple Person
class with a getName()
that returns a String
:
public class Person {
public String getName() {...}
}
How do I use LambdaMetafactory
to create a lamdba for that at runtime?
Here's what I got this far:
public static void main(String[] args) {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType invokedType = MethodType.methodType(GetterFunction.class);
MethodType methodType = MethodType.methodType(Object.class);
MethodType actualMethodType = MethodType.methodType(String.class);
CallSite site;
try {
MethodHandle virtual = lookup.findVirtual(Person.class, "getName", actualMethodType);
site = LambdaMetafactory.metafactory(lookup,
"getName",
invokedType,
methodType,
virtual,
methodType);
} catch (LambdaConversionException | NoSuchMethodException | IllegalAccessException e) {
throw new IllegalArgumentException(e);
}
GetterFunction getterFunction;
try {
getterFunction = (GetterFunction) site.getTarget().invokeExact();
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
System.out.println(getterFunction.getName(new Person("Ann")));
}
@FunctionalInterface
private interface GetterFunction {
String getName(Person person);
}
Which throws:
java.lang.invoke.LambdaConversionException: Incorrect number of parameters for instance method invokeVirtual foo.Person.getName:()String; 0 captured parameters, 0 functional interface method parameters, 0 implementation parameters
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:193)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
Aucun commentaire:
Enregistrer un commentaire