My goal is to create a MethodHandle that, by passing a class and a field name, reads that field with a MethodHandle getter and returns the value.
With this method I wanted to return an arbitrary object:
return new ConstantCallSite(MethodHandles.lookup().unreflectGetter(f).asType(MethodType.methodType(Object.class))).dynamicInvoker();
I received the Field f via Reflections. The problem now is that when this method is executed, the typical error for invokeExact (WrongMethodTypeException) occurs:
WrongMethodTypeException: cannot convert MethodHandle(TestClass)String to ()Object
This also applies to ints, floats, etc. In another thread I also already read that you can use invokeExact dynamically if the return of MethodHandle is changed to Object. Here is a code snippet from the method, which makes use of passing a static final MethodHandle:
return (T) handle.invokeExact(testObject);
Using MethodHandle#invoke is rather out of the question for me, as I'm after performance. Without invokeExact I could possibly also fall back on using only reflections.
Does anyone know a way to do this or a workaround with similar performance? The latter plays a big role in the project. I thank those in advance who could possibly help with this problem.
CodePudding user response:
A (non-static) getter needs an instance to retrieve the field's value from. You should be able to make this work by adding another Object
parameter to the erased method type:
return MethodHandles.lookup().unreflectGetter(f).asType(MethodType.methodType(Object.class, Object.class));
(Also, there's no need to wrap the thing in a ConstantCallsite
)