mercredi 2 décembre 2015

Can MethodHandle be used by frameworks/libraries (instead of traditional reflection)?

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