更改 java 中的静态最终字段 12+
Change static final field in java 12+
这个问题与Change private static final field using Java reflection密切相关。有人问,如何更改 private static final
变量。
但是,该问题的答案在 Java 12+ 中不起作用,因为您无法使用反射访问 java.lang.reflect.Field
的私有变量。
尽管如此,当您尝试这样做时,您最终会得到如下堆栈跟踪:
Exception java.lang.NoSuchFieldException: modifiers
at Class.getDeclaredField (Class.java:2412)
at <your call of Field.class.getDeclaredField("modifiers").setAccessible(true)>
有什么方法可以改变这些版本中的常量吗?
我可以想象可以利用 JNI/JNA。
您可以使用 Unsafe
.
public class Example
{
// javac will inline static final Strings, so let's say it's Object
private static final Object changeThis = "xxx";
public static void main(String... args) throws Exception
{
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
System.out.println("before = " + changeThis);
final Field ourField = Example.class.getDeclaredField("changeThis");
final Object staticFieldBase = unsafe.staticFieldBase(ourField);
final long staticFieldOffset = unsafe.staticFieldOffset(ourField);
unsafe.putObject(staticFieldBase, staticFieldOffset, "it works");
System.out.println("after = " + changeThis);
}
}
结果:
before = xxx
after = it works
这个问题与Change private static final field using Java reflection密切相关。有人问,如何更改 private static final
变量。
但是,该问题的答案在 Java 12+ 中不起作用,因为您无法使用反射访问 java.lang.reflect.Field
的私有变量。
尽管如此,当您尝试这样做时,您最终会得到如下堆栈跟踪:
Exception java.lang.NoSuchFieldException: modifiers
at Class.getDeclaredField (Class.java:2412)
at <your call of Field.class.getDeclaredField("modifiers").setAccessible(true)>
有什么方法可以改变这些版本中的常量吗?
我可以想象可以利用 JNI/JNA。
您可以使用 Unsafe
.
public class Example
{
// javac will inline static final Strings, so let's say it's Object
private static final Object changeThis = "xxx";
public static void main(String... args) throws Exception
{
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
System.out.println("before = " + changeThis);
final Field ourField = Example.class.getDeclaredField("changeThis");
final Object staticFieldBase = unsafe.staticFieldBase(ourField);
final long staticFieldOffset = unsafe.staticFieldOffset(ourField);
unsafe.putObject(staticFieldBase, staticFieldOffset, "it works");
System.out.println("after = " + changeThis);
}
}
结果:
before = xxx
after = it works