Java – change the final variable through reflection. Why is there a difference between static and non static final variables

Please refer to the code below

My question is why exceptions are not thrown in the case of non - static final variables, and vice versa Why is there a difference?

import java.lang.reflect.Field;
import java.util.Random;

public class FinalReflection {

    final static int stmark =  computeRandom();
    final int inmark = computeRandom();

    public static void main(String[] args) throws SecurityException,NoSuchFieldException,IllegalArgumentException,illegalaccessexception {
        FinalReflection obj = new FinalReflection();
        System.out.println(FinalReflection.stmark);
        System.out.println(obj.inmark);
        Field staticFinalField  = FinalReflection.class.getDeclaredField("stmark");
        Field instanceFinalField  = FinalReflection.class.getDeclaredField("inmark");
        staticFinalField.setAccessible(true);
        instanceFinalField.setAccessible(true);

        instanceFinalField.set(obj,100);
        System.out.println(obj.inmark);

        staticFinalField.set(FinalReflection.class,101);
        System.out.println(FinalReflection.stmark);

    }

    private static int computeRandom() {
        return new Random().nextInt(5);
    }
}

Solution

FinalReflectionobj = new FinalReflection();
FinalReflectionobj = new FinalReflection();
System.out.println(FinalReflection.stmark);
System.out.println(obj.inmark);
Field staticFinalField  = FinalReflection.class.getDeclaredField("stmark");
Field instanceFinalField  = FinalReflection.class.getDeclaredField("inmark");
staticFinalField.setAccessible(true);
instanceFinalField.setAccessible(true);

//EXTRA CODE
//Modify the final using reflection
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(staticFinalField,staticFinalField.getModifiers() & ~Modifier.FINAL);


instanceFinalField.set(obj,100);
System.out.println(obj.inmark);
staticFinalField.set(FinalReflection.class,101);
System.out.println(FinalReflection.stmark);

This solution does not have any disadvantages, it may not work in all cases:

If the final field is initialized as a compile time constant in the field declaration, changes to the final field may not be visible because using the final field at compile time will be replaced with a compile time constant

Another problem is that the specification allows active optimization of the final domain In a thread, it is allowed to reorder the reading of the final field with the modification of the final field that does not occur in the constructor This is also a similar problem in more

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>