【发布时间】:2015-12-03 19:23:03
【问题描述】:
在我的框架中,我有一个这样的类:
public class Foo<B, V> {
private final Method getterMethod;
...
public V executeGetter(B bean) {
try {
return getterMethod.invoke(bean);
} catch ...
}
}
此类用于调用由用户创建的类的 getter,这些类在我的框架编译时不可用。例如,B 可能是一个名为 Person 的类。
通过分析,我发现这种方法非常慢。 Method.invoke() 在采样分析中占用了 40% 的性能(即使使用 setAccessible(true)),而非反射实现仅占用该性能的一小部分。
所以我想用 MethodHandle 替换 is:
public class Foo<B, V> {
private final MethodHandle getterMethodHandle;
...
public V executeGetter(B bean) {
try {
return getterMethodHandle.invoke(bean);
} catch ...
}
}
然后我得到了这个异常:
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)
即使bean 是Person 的一个实例。现在误导部分是它试图将Object[](而不是Object)转换为Person。请注意,将其包装在对象数组中(这是一种性能损失)并没有帮助:
return getterMethodHandle.invoke(new Object[]{bean}); // Same exception
是否可以让MethodHandle 在这种情况下工作?
【问题讨论】:
-
你能添加完整的堆栈跟踪吗?
-
你是如何构建
getterMethodHandle的? -
添加了堆栈跟踪。使用 JDK 7 进行记录。
-
句柄构造如下:
getterMethodHandle = lookup.unreflect(getterMethod);
标签: java reflection methodhandle