Change private static final field using Java reflection

前端 未结 12 2346
天涯浪人
天涯浪人 2020-11-21 05:52

I have a class with a private static final field that, unfortunately, I need to change it at run-time.

Using reflection I get this error: java.lan

12条回答
  •  梦毁少年i
    2020-11-21 06:07

    The accepted answer worked for me until deployed on JDK 1.8u91. Then I realized it failed at field.set(null, newValue); line when I had read the value via reflection before calling of setFinalStatic method.

    Probably the read caused somehow different setup of Java reflection internals (namely sun.reflect.UnsafeQualifiedStaticObjectFieldAccessorImpl in failing case instead of sun.reflect.UnsafeStaticObjectFieldAccessorImpl in success case) but I didn't elaborate it further.

    Since I needed to temporarily set new value based on old value and later set old value back, I changed signature little bit to provide computation function externally and also return old value:

    public static  T assignFinalField(Object object, Class clazz, String fieldName, UnaryOperator newValueFunction) {
        Field f = null, ff = null;
        try {
            f = clazz.getDeclaredField(fieldName);
            final int oldM = f.getModifiers();
            final int newM = oldM & ~Modifier.FINAL;
            ff = Field.class.getDeclaredField("modifiers");
            ff.setAccessible(true);
            ff.setInt(f,newM);
            f.setAccessible(true);
    
            T result = (T)f.get(object);
            T newValue = newValueFunction.apply(result);
    
            f.set(object,newValue);
            ff.setInt(f,oldM);
    
            return result;
        } ...
    

    However for general case this would not be sufficient.

提交回复
热议问题