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?