Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change static final field in java 12+

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.

like image 979
dan1st Avatar asked Aug 25 '26 06:08

dan1st


1 Answers

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
like image 158
northpl93 Avatar answered Aug 26 '26 21:08

northpl93



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!