I want to convert a Record's constructor to a Function<Object[], T> using lambdametafactory (T is a generic type), here are my codes:
public record R(
String a,
String b
) {
}
private static void testRecord() throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle constructor = lookup.findConstructor(R.class, MethodType.methodType(void.class, String.class, String.class));
constructor = constructor.asSpreader(Object[].class, 2);
R r = (R) constructor.invokeExact(new Object[]{"a", "b"});
System.out.println(r.a());
System.out.println(r.b());
MethodType methodType = constructor.type();
CallSite callSite = LambdaMetafactory.metafactory(lookup,
"apply",
MethodType.methodType(Function.class),
methodType.erase(),
constructor,
methodType);
Function<Object[], R> f = (Function<Object[], R>) callSite.getTarget().invokeExact();
R apply = f.apply(new Object[]{"a", "b"});
System.out.println(apply.a());
System.out.println(apply.b());
}
When using constructor.invokeExact()
method, the record could be instantiated successfully, but the CallSite
couldn't be generated by LambdaMetafactory.metafactory()
method because of following errors:
Exception in thread "main" java.lang.invoke.LambdaConversionException: MethodHandle(Object[])R is not direct or cannot be cracked
at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.<init>(AbstractValidatingLambdaMetafactory.java:143)
at java.base/java.lang.invoke.InnerClassLambdaMetafactory.<init>(InnerClassLambdaMetafactory.java:168)
at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:336)
How can I fix this?
Aucun commentaire:
Enregistrer un commentaire