使用MethodHandles调用在编译时不知道的类的方法(没有反射)

时间:2017-12-21 13:31:57

标签: java methodhandle

我需要调用getName()类的Person方法,而不知道Person类作为编译时间并使用MethodHandle(而不是正常反射)。

所以我希望此代码能够正常工作(此代码无法更改):

MyGetterAccessor myGA = new MyGetterAccessor(Person.class, "getName", String.class)
assertEquals("Ann", myGA.call(new Person("Ann"));
assertEquals("Beth", myGA.call(new Person("Beth"));

这是我的方法处理代码,不能使用" Person" (这可以改变以使其工作):

public class MyGetterAccessor {

    MethodHandle mh;

    public GetterAccessor(Class entityClass, String methodName, Class returnType) {
        mh = MethodHandles.lookup().findVirtual(entityClass, methodName, MethodType.methodType(returnType));
    }

    public Object call(Object entity) {
        return mh.invokeExact(entity);
    }

}

但是WrongMethodTypeException失败了。有任何建议如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

也许

public static <T,R> setValue(T setTo, BiFunction<T,String,R> setter, String value) {
    return setter.apply(setTo, value);
}

assertEquals("Ann", setValue(new Person(), Person::set, "Ann"));

或者那不够反思?

答案 1 :(得分:0)

FWIW,这可行,但it's slow in java 8 in my benchmarks

MethodHandle temp = lookup.findVirtual(getterMethod.getDeclaringClass(), getterMethod.getName(), MethodType.methodType(returnType));
temp = temp.asType(temp.type().changeParameterType(0 , Object.class));
getterMethodHandle = temp.asType(temp.type().changeReturnType(Object.class));