使用反射更改静态最终File.separatorChar进行单元测试?

使用反射更改静态最终File.separatorChar进行单元测试?,第1张

使用反射更改静态最终File.separatorChar进行单元测试?

从文档中

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


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5176386.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-18
下一篇 2022-11-18

发表评论

登录后才能评论

评论列表(0条)

保存