Spring ReflectionTestUtils没有设置静态的final字段

时间:2018-07-25 14:48:17

标签: java spring reflection

我有一个像这样的静态最终字段:

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

并且我正在尝试像这样更改测试中的字段:

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

但它不起作用并显示

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

2 个答案:

答案 0 :(得分:0)

强烈建议不要更改静态最终值。

但是,如果您确实需要它,可以使用以下代码。 (仅在(包括)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);
  }

编辑

还要注意,您不能更改编译期常量。例如HW

public static final String HW = "Hello World".

编译时将内联。

答案 1 :(得分:0)

这对我有用。例如,我们有以下类别的对象

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

然后在单元测试中,我们可以这样写。我使用了org.powermock.reflect.Whitebox及其setInternalState方法:

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