- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在 Java 中,事实证明字段访问器会被缓存,并且使用访问器会产生副作用。例如:
class A {
private static final int FOO = 5;
}
Field f = A.class.getDeclaredField("FOO");
f.setAccessible(true);
f.getInt(null); // succeeds
Field mf = Field.class.getDeclaredField("modifiers" );
mf.setAccessible(true);
f = A.class.getDeclaredField("FOO");
f.setAccessible(true);
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.setInt(null, 6); // fails
鉴于
class A {
private static final int FOO = 5;
}
Field mf = Field.class.getDeclaredField("modifiers" );
mf.setAccessible(true);
f = A.class.getDeclaredField("FOO");
f.setAccessible(true);
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.setInt(null, 6); // succeeds
这是失败的堆栈跟踪的相关位:
java.lang.IllegalAccessException: Can not set static final int field A.FOO to (int)6
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:100)
at sun.reflect.UnsafeQualifiedStaticIntegerFieldAccessorImpl.setInt(UnsafeQualifiedStaticIntegerFieldAccessorImpl.java:129)
at java.lang.reflect.Field.setInt(Field.java:949)
这两个反射访问当然发生在我的代码库的不同部分,我真的不想更改第一个来修复第二个。有没有办法改变第二个反射访问以确保它在两种情况下都成功?
我尝试查看 Field
对象,但它没有任何看起来有用的方法。在调试器中,我注意到 overrideFieldAccessor
设置在第一个示例中返回的第二个 Field
上,并且没有看到对修饰符的更改。不过,我不确定该怎么做。
如果有影响,我正在使用 openjdk-8
。
最佳答案
如果你想让修饰符 hack(不要忘记 it is a total hack)起作用,你需要在你第一次访问字段。
因此,在执行 f.getInt(null);
之前,您需要执行以下操作:
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
原因是,无论有多少不同的实际java.lang.reflect.Field
,为类的每个字段(*)只创建一个内部FieldAccessor
对象> 你拥有的元素。当它在 UnsafeFieldAccessorFactory
中构造 FieldAccessor 实现时,对 final
修饰符的检查就完成了一次。 .
当确定您无法访问 final static
字段时(因为 setAccessible
覆盖不起作用,但非静态 final 字段,但不适用于 static
final fields),即使通过不同的 Field
对象,它也会在每次后续反射中不断失败,因为它一直使用相同的 FieldAccessor
。
(*) 禁止同步问题;作为 Field
的源代码在评论中提到:
// NOTE that there is no synchronization used here. It is correct (though not efficient) to generate more than one FieldAccessor for a given Field.
关于在先前的反射之后设置静态最终字段的 Java 反射失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48198108/
我的应用将 SceneKit 内容的“页面”与图像和文本交替。当我从图像页面前进到新的 SceneKit 页面时,前一个 SceneKit 页面中的内容会短暂显示,然后被新内容替换。时髦。 我只使用一
我正在尝试处理(在 C# 中)包含一些数字数据的大型数据文件。给定一个整数数组,如何对其进行拆分/分组,以便如果下一个 n(两个或更多)是负数,则前一个 n 元素被分组。例如,在下面的数组中,应该使用
刚接触promises,研究过。所以我的代码和我的理解: sql.connect(config).then(function(connection) { return connection.req
目前我在 if (roobaf) block 中有一些代码,这取决于 foo 和 bar 是否为假。我可以在 block 内再次检查这些条件,但感觉像是不必要的代码重复。 if (foo) {
我是一名优秀的程序员,十分优秀!