I am trying to use LambdaMetafactory to replace reflection,but I have a problem.If I use a specific class then it works well,just like this:
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType type = MethodType.methodType(ResponseMsg.class,Map.class);
MethodHandle mh = lookup.findVirtual(TestService.class,"testMethod",type);
TestService ins = TestService.getInstance();
MethodHandle factory = LambdaMetafactory.metafactory(
lookup, "apply", MethodType.methodType(Function.class,TestService.class),
type.generic(), mh, type).getTarget();
factory.bindTo(ins);
Function lambda = (Function) factory.invokeExact(ins);
But if I use Class<?>
to replace the specific class ,then it won't work,just like this:
public static Function generateLambda(@NotNull Class<?> cls,@NotNull String method) {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType type = MethodType.methodType(RETURN_TYPE,PARM_TYPE);
try {
MethodHandle mh = lookup.findVirtual(cls,method,type);
Object instance = getInstance(cls);
if(instance == null) {
return null;
}
MethodHandle factory = LambdaMetafactory.metafactory(
lookup, "apply", MethodType.methodType(Function.class,cls),
type.generic(), mh, type).getTarget();
factory.bindTo(cls.cast(instance));
return (Function) factory.invokeExact(cls.cast(instance));
} catch (Throwable e) {
logger.error("get Function fail, cause :" ,e);
return null;
}
}
Here is the exception:
java.lang.invoke.WrongMethodTypeException: expected (TestService)Function but found (Object)Function
at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:298)
at java.lang.invoke.Invokers.checkExactType(Invokers.java:309)
at com.utils.cache.ClassUtils.generateLambda(ClassUtils.java:182)
The Line 182 is:
return (Function) factory.invokeExact(cls.cast(instance));
I know just use static method can solve this problem,but I want to know is there any other way to solve it without changing the non-static to static.
Aucun commentaire:
Enregistrer un commentaire