Java 快速编辑私有变量
在我的项目中,我希望快速读取私有ish变量并对其进行修改。我最初打算进行反思,但我的想法是这样做效率太低Java 快速编辑私有变量,java,reflection,Java,Reflection,在我的项目中,我希望快速读取私有ish变量并对其进行修改。我最初打算进行反思,但我的想法是这样做效率太低 //Reference for what I need to get data from. public class SomeControllerInALibraryThatICantEdit { //I can easily get an instance of the controller public static final SomeControllerInLarg
//Reference for what I need to get data from.
public class SomeControllerInALibraryThatICantEdit {
//I can easily get an instance of the controller
public static final SomeControllerInLargeLibrary instance;
//I need to read from and make changes to the data object quickly.
//It is final, so I don't need to worry about this object changing or being reset.
private final Subclass dataClass = new Subclass();
private class Subclass {
//I can get a pointer to this once then treat it like any other array.
public float[] arr;
//This is the problematic part. I need to be able to quickly check changes and
//set this every update. Keeping in mind there are multiple dataPoints.
public short dataPoint;
}
}
获取和设置数据点的快速有效方法是什么?我可以使用反射,但我希望有更好的方法来解决这个问题。我能否以某种方式创建一个表示子类并将它们的指针链接在一起的Pojo
如果我只是用叉子叉图书馆,让它在我所做的工作中更好地工作,那么这就违背了我项目的目的
但我知道使用反射是非常缓慢的
事实并非如此
为该变量创建私有静态final MethodHandle,它将被优化到与使用普通代码几乎相同的性能-可以肯定的是,调用它的次数将比调用它的次数少很多,因此您也可以每秒调用它200次,而不是2000次。仅创建反射访问器非常慢,但您只需要执行一次
private static final MethodHandle dataGetter;
static {
Field dataField;
try {
dataField = SomeControllerInALibraryThatICantEdit.class.getDeclaredField("dataClass");
dataField.setAccessible(true); // or trySetAccessible for new java
dataGetter = MethodHandles.lookup().unreflectGetter(dataField);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
并使用类似于:
DataClass data = (DataClass) dataGetter.invokeExact(SomeControllerInALibraryThatICantEdit.instance);
注意,即使invokeExact方法需要签名中的对象,也必须提供有效类型的变量,因为它使用@PolymorphicSignature
您还可以使用:
dataGetter = MethodHandles.lookup().unreflectGetter(dataField).bindTo(SomeControllerInALibraryThatICantEdit.instance);
然后,您可以跳过实例,它可能也会快一点
这里唯一慢的部分是MethodHandle的创建。但性能也可能依赖于JVM,就像我认为在android虚拟机上,JVM的速度通常较慢一样 但在hotspot上,速度应该非常快,以下是我以前的基准测试结果:
Benchmark Mode Cnt Score Error Units
normalDirectAccess avgt 10 2,867 ± 0,142 ns/op
somethingPrivateFieldAccessor_static_final_handle_access avgt 10 2,827 ± 0,058 ns/op
somethingPrivateFieldAccessor_static_final_handle_bound_access avgt 10 2,859 ± 0,084 ns/op
完整的基准可以在这里找到:像其他类型的反射等,但这一小部分应该足以回答这个问题
此外,由于此字段是最终字段,且在单例中。。。您可能只需获取一次,然后重复使用您的问题没有意义什么部分?我希望能够读取和设置数据点,但我想尝试找到一种比每次需要时使用反射更快的方法(大约每秒200次)。你没有解释为什么首先需要使用反射为什么不能简单地使用getter/setter?你能详细解释一下为什么你认为反思在这里是必要的吗?当你说“快”的时候,你在问什么?如果你还不能获得或设置它,你怎么知道你选择的任何方式都不够快?