我们知道,反射是一种灵活但缓慢的方法,用于在运行时维护和修改代码的行为.
但是如果我们必须使用这样的功能,那么与用于动态修改的Reflection API相比,Java中是否有更快的编程技术?这些替代品反对反思的利弊是什么?
我正在写一些调用的代码Field.set和Field.get数千次.显然,由于反射,这是非常缓慢的.
我想看看我是否可以MethodHandle在Java7中提高性能.到目前为止,这就是我所拥有的:
而不是field.set(pojo, value),我正在做:
private static final Map<Field, MethodHandle> setHandles = new HashMap<>();
MethodHandle mh = setHandles.get(field);
if (mh == null) {
mh = lookup.unreflectSetter(field);
setHandles.put(field, mh);
}
mh.invoke(pojo, value);
Run Code Online (Sandbox Code Playgroud)
但是,这似乎没有比使用反射的Field.set调用更好.我在这里做错了吗?
我读到使用invokeExact可能会更快,但当我尝试使用它时,我得到了一个java.lang.invoke.WrongMethodTypeException
有没有人成功地优化了对Field.set或Field.get的重复调用?
我尝试在我的一个脚本中获得最大性能,而不进行重大重构。
我发现了使用反射从 Field 创建 BiConsumer 的方法。
return (c, v) -> {
try {
field.set(c, v);
} catch (final Throwable e) {
throw new RuntimeException("Could not set field: " + field, e);
}
};
Run Code Online (Sandbox Code Playgroud)
反射有缓慢的名声。所以我想我可以使用方法句柄。
Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.unreflectSetter(field);
return (c, v) -> {
try {
mh.invoke(c, v);
} catch (final Throwable e) {
throw new RuntimeException("Could not set field: " + field, e);
}
};
Run Code Online (Sandbox Code Playgroud)
这已经快了一点点。然而BiConsumer,它FunctionalInterface可以以某种方式生成。
public static <C, V> BiConsumer<C, V> …Run Code Online (Sandbox Code Playgroud)