简体   繁体   中英

Spring ReflectionTestUtils does not set static final field

I have a static final field like this:

class SomeClass {
    static final String CONST = "oldValue";
}

and i'm trying to change that field in test like this:

ReflectionTestUtils.setField(SomeClass.class, "CONST", "newValue");

but it doesn't work and says

java.lang.IllegalStateException: Could not access method: Can not set static final java.lang.String field

It is highly recommanded do not change a static final value.

But if you really need it, you can use following code. (Only work before(include) java-8)

  static void setFinalStatic(Field field, Object newValue) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
    field.setAccessible(true);

    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

    field.set(null, newValue);
  }

EDIT

Also notice that you can't change a compile-period constant. Such as this HW

public static final String HW = "Hello World".

It will be inline when compile.

This works for me. Eg we have an object of the following class

public class LogExample {
     private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
 }

Then in the unit tests we could write like this. I used org.powermock.reflect.Whitebox and its setInternalState method:

import static org.powermock.reflect.Whitebox.setInternalState;
...
Logger log = mock(Logger.class);
setInternalState(logExample.getClass(), "log", log);
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM