While playing with introspection, I found an interesting situation where:
true
false
(note the output in the Console tab):I am trying to set the value of the private final static
field, I guess I did it wrong?
What is actually happening here?
import java.lang.reflect.*;
public class Main {
private final static boolean VAR = false; // I want to dynamically set this to true
public static void main(String[] args) throws Exception {
Field field = Main.class.getDeclaredField("VAR");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, true);
System.out.println(VAR);
}
}
The compiler is 'inlining' the static final
value. If you look at the bytecode for the println
you will see something like:
iconst_0
invokevirtual java.io.PrintStream.println(boolean)
Because it knows the value won't change the compiler has generated code which is loading the value 0 (for false) directly without referring to the VAR
variable so your change to the variable is ignored.
Because of the inlining you can't rely on being able to change the value of a static final
variable with reflection.