从文档中
Field.set:
如果基础字段是final,则该方法将为该字段成功地抛出
IllegalAccessException除非setAccessible(true),
并且该字段是非静态的 。
因此,在第一看来,你的运气了,因为
File.separatorChar是
static。令人惊讶的 是
一种方法来解决这个问题:简单地让
static现场不再
final通过反射。
我从javaspecialistist.eu修改了此解决方案:
static void setFinalStatic(Field field, Object newValue) throws Exception { field.setAccessible(true); // remove final modifier from field Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.set(null, newValue);}
我已经对其进行了测试,并且可以正常工作:
setFinalStatic(File.class.getField("separatorChar"), '#');System.out.println(File.separatorChar); // prints "#"
使用这种技术时要格外小心 。除了毁灭性的后果,以下内容确实有效:
setFinalStatic(Boolean.class.getField("FALSE"), true);System.out.format("Everything is %s", false); // "Everything is true"
重要更新 :上述解决方案 并非
在所有情况下都适用。如果使该字段可访问并且在重置前通读了Reflection,
IllegalAccessException则会抛出一个。失败是因为Reflection
API创建了内部
FieldAccessor对象,这些内部对象被缓存和重用(请参阅java.lang.reflect.Field#acquireFieldAccessor(boolean)实现)。测试代码示例失败:
Field f = File.class.getField("separatorChar"); f.setAccessible(true); f.get(null);// call setFinalStatic as before: throws IllegalAccessException
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)