Nic*_*cnl 5 java reflection static final field
我正在尝试使用Java Reflection更改私有静态final字段.但它只是失败了.有人有想法吗?
这是我的代码:
public class SecuredClass {
private static final String securedField = "SecretData";
public static String getSecretData() { return securedField; }
}
Run Code Online (Sandbox Code Playgroud)
public class ChangeField {
static void setFinalStatic(Field field, Object newValue) throws Exception
{
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~ Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String args[]) throws Exception
{
System.out.println("Before = " + SecuredClass.getSecretData());
Field stringField = SecuredClass.class.getDeclaredField("securedField");
stringField.setAccessible(true);
setFinalStatic(stringField, "Screwed Data!");
System.out.println("After = " + Java_FileMerger_Main.getSecretData());
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出:
Before = SecretData
After = SecretData
Run Code Online (Sandbox Code Playgroud)
我试图用System.setSecurityManager(null)删除SecurityManager; 但它没有改变任何东西.我知道这是邪恶的,但我想让它发挥作用.我希望有人可以帮助我.
通过反射改变最终字段的语义没有定义(参见规范).不能保证在从场上读取时会看到对最终场的反射写入.
特别是对于具有常量分配的静态最终字段(如在您的情况下),编译器通常会内联常量,因此在运行期间根本不会访问该字段(仅当您使用反射时).
SecurityManager与此处无关.如果SecurityManager禁止使用反射,则操作将抛出异常,并且不会以静默方式失败.
问题的答案使用Java反射更改私有静态最终字段提供了一些更多细节,包括一个示例,您可以在字节代码中看到常量被内联.