I'm trying to replace a reflective invocation with a MethodHandle, but varargs seem to be impossible to deal with.
My reflective invoker currently looks like this:
public class Invoker {
private final Method delegate;
public Invoker(Method delegate) {
this.delegate = delegate;
}
public Object execute(Object target, Object[] args) {
return delegate.invoke(target, args);
}
}
My current attempt at rewriting it looks like this (the interface the Invoker
exposes has to stay the same):
public class Invoker {
private final Method delegate;
private final MethodHandle handle;
public Invoker(Method delegate) {
this.delegate = delegate;
this.handle = MethodHandles.lookup().unreflect(delegate);
}
public Object execute(Object target, Object[] args) throws InvocationTargetException, IllegalAccessException {
Object[] allArgs = merge(target, args);
return handle.invokeWithArguments(allArgs);
}
}
And this works just fine in most cases. But varargs break everything. E.g. have a method like:
public String test(int i, String... args) {
return ...;
}
And the above will fail. I tried various combinations of asSpreader()
, MethodHandles.explicitCastArguments()
, invoke
instead of invokeWithArguments
etc with 0 success.
The only way I can invoke a varargs method is to provide the arguments inline and not as an array (e.g. handle.invokeWithArguments(args1, args2...)
), but I can not do that and maintain the generic nature of the Invoker
that it currently has.
Is this really impossible to do the way I'm trying?
Aucun commentaire:
Enregistrer un commentaire