使用 Java 反射更改私有静态最终字段 [英] Change private static final field using Java reflection

查看:42
本文介绍了使用 Java 反射更改私有静态最终字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 private static final 字段的类,不幸的是,我需要在运行时更改它.

I have a class with a private static final field that, unfortunately, I need to change it at run-time.

使用反射我得到这个错误:java.lang.IllegalAccessException: Can not set static final boolean field

Using reflection I get this error: java.lang.IllegalAccessException: Can not set static final boolean field

有什么办法可以改变这个值吗?

Is there any way to change the value?

Field hack = WarpTransform2D.class.getDeclaredField("USE_HACK");
hack.setAccessible(true);
hack.set(null, true);

推荐答案

假设没有 SecurityManager 阻止您这样做,您可以使用 setAccessible 绕过 private 并重置修饰符去掉final,实际上修改了一个private static final 字段.

Assuming no SecurityManager is preventing you from doing this, you can use setAccessible to get around private and resetting the modifier to get rid of final, and actually modify a private static final field.

这是一个例子:

import java.lang.reflect.*;

public class EverythingIsTrue {
   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 {      
      setFinalStatic(Boolean.class.getField("FALSE"), true);

      System.out.format("Everything is %s", false); // "Everything is true"
   }
}

假设没有抛出SecurityException,上面的代码打印Everything is true".

Assuming no SecurityException is thrown, the above code prints "Everything is true".

这里实际做的事情如下:

What's actually done here is as follows:

  • main 中的原始 booleantruefalse 被自动装箱为引用类型 Boolean 常数"Boolean.TRUEBoolean.FALSE
  • 反射用于更改public static final Boolean.FALSE 引用Boolean.TRUE
  • 引用的Boolean
  • 因此,随后每当 false 自动装箱为 Boolean.FALSE 时,它引用的 Boolean 与所引用的相同通过 Boolean.TRUE
  • 所有 假" 现在都是 真"
  • The primitive boolean values true and false in main are autoboxed to reference type Boolean "constants" Boolean.TRUE and Boolean.FALSE
  • Reflection is used to change the public static final Boolean.FALSE to refer to the Boolean referred to by Boolean.TRUE
  • As a result, subsequently whenever a false is autoboxed to Boolean.FALSE, it refers to the same Boolean as the one refered to by Boolean.TRUE
  • Everything that was "false" now is "true"
查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆