In my framework I have a class like this:
public class Foo<B, V> {
private final Method getterMethod;
...
public V executeGetter(B bean) {
try {
return getterMethod.invoke(bean);
} catch ...
}
}
This class is used to call getters of classes created by users that aren't available at compile time of my framework. For example, B
might be a class called Person
.
Through profiling, I've discovered that this method is horribly slow. The Method.invoke()
takes 40% of performance in sampling profiling (even with setAccessible(true)
), while a non reflective implementation takes only a small fraction of that performance.
So I 'd like to replace is with a MethodHandle
:
public class Foo<B, V> {
private final MethodHandle getterMethodHandle;
...
public V executeGetter(B bean) {
try {
return getterMethodHandle.invoke(bean);
} catch ...
}
}
But then I get this exception:
java.lang.ClassCastException: Cannot cast [Ljava.lang.Object; to Person
at sun.invoke.util.ValueConversions.newClassCastException(ValueConversions.java:461)
at sun.invoke.util.ValueConversions.castReference(ValueConversions.java:456)
at ...Foo.executeGetter(Foo.java:123)
even though bean
is an instance of Person
. Now the misleading part is that it's trying to cast an Object[]
(and not an Object
) to Person
. Note that wrapping it in an object array (which is a performance loss) doesn't help:
return getterMethodHandle.invoke(new Object[]{bean}); // Same exception
Is it possible to get the MethodHandle
to work in this situation?
Aucun commentaire:
Enregistrer un commentaire