0

I try to change the int value of a private static final int for unittesting. I looked at http://zarnekow.blogspot.de/2013/01/java-hacks-changing-final-fields.html and http://java-performance.info/updating-final-and-static-final-fields/ and other stackoverflow examples like: changing final variables through reflection, why difference between static and non-static final variable

30 Seconds is a default timer. i want to set it with setOverReflectionMax_SECONDS(3); to 3 seconds. But it does not work, any hints ?

My baseclass with

public class BaseClass {

    private static final int MAX_SECONDS = 30;

}

and other class

public final class MyClass extends BaseClass {

    public static List<Field> getFields(final Class<?> clazz){
        final List<Field> list = new ArrayList<>();
        list.addAll(Arrays.asList(clazz.getDeclaredFields()));

        if(clazz.getSuperclass() != null){
            list.addAll(getFields(clazz.getSuperclass()));
        }
        return list;
    }

    public static void setOverReflectionMax_SECONDS(final int newValue) {

        final List<Field> fields = getFields(MyClass.class);
        for (final Field field : fields) {
            if (field.getName().equals("MAX_SECONDS")) {

                field.setAccessible(true);   //EDIT 4 

                Field modifiersField;
                try {
                    modifiersField = Field.class.getDeclaredField("modifiers");
                    modifiersField.setAccessible(true);
                    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
                    field.set(null, newValue);
                } catch (final Exception e2) {
                    e2.printStackTrace();
                }

            }
        }
    }

}

Edit1: wrong classname

Edit2: I cant change BaseClass (got only the .class file)

Edit3: new Exception

Class MyClass can not access a member of class BaseClass with modifiers "private static"

Edit4 : see code , fixes the exception, but it does not change the int

Community
  • 1
  • 1
svenhornberg
  • 14,376
  • 9
  • 40
  • 56

1 Answers1

0

This may not be possible even using reflection, because the value of the field may be inlined by the compiler (I believe the compiler is free to choose whether it does this or not). In that case, a copy of the value is hardcoded where it is actually used, and can be changed only by manipulating the byte code.

This is explained in more detail in this question: Change private static final field using Java reflection.

tl,dr: There is no way to reliably change a static final field using reflection. Your options are:

  • manipulate the byte code (a rather desperate option)
  • find another solution (subclass, wrapper, proxy...)
  • (bug the author to) change the source code, to make the value settable/configurable
Community
  • 1
  • 1
sleske
  • 81,358
  • 34
  • 189
  • 227