英文:
Change static final field in java 12+
问题
这个问题与使用Java反射更改私有静态常量字段密切相关。在那里,有人问如何更改private static final
变量。
然而,那个问题的回答在Java 12+中不起作用,因为您无法使用反射访问java.lang.reflect.Field
的私有变量。
尽管如此,如果您尝试这样做,您将会得到一个类似以下的堆栈跟踪:
Exception java.lang.NoSuchFieldException: modifiers
at Class.getDeclaredField (Class.java:2412)
at <调用Field.class.getDeclaredField("modifiers").setAccessible(true)>
在这些版本中是否有任何更改此类常量的方法?
我可以想象可以利用JNI/JNA来实现。
英文:
This question is strongly related to Change private static final field using Java reflection. There, it was asked, how to change a private static final
variable.
However, the answers on that question do not work in Java 12+ as you cannot access private variables of java.lang.reflect.Field
using Reflection.
When you try to do it despite that, you will end up with a stack trace like:
Exception java.lang.NoSuchFieldException: modifiers
at Class.getDeclaredField (Class.java:2412)
at <your call of Field.class.getDeclaredField("modifiers").setAccessible(true)>
Is there any way to change such a constant in those versions?
I could imagine being possible utilizing JNI/JNA.
答案1
得分: 15
你可以使用 Unsafe
。
public class Example
{
// javac 将会内联静态 final 字符串,所以假设它是 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
英文:
You can use 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);
}
}
Result:
before = xxx
after = it works
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论