Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

changing final variables through reflection, why difference between static and non-static final variable

Please refer to the below code. When I run the code, I am able to change the value of a final non-static variable. But if I try to change the value of a final static variable then it throws java.lang.IllegalAccessException.

My question is why doesn't it throw an exception in case of non-static final variable also or vice versa. Why the 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);
    }
}
like image 996
veritas Avatar asked Aug 08 '13 11:08

veritas


People also ask

Can you explain the difference between static variable and final static variable?

The static keyword means the value is the same for every instance of the class. The final keyword means once the variable is assigned a value it can never be changed. The combination of static final in Java is how to create a constant value.

What is final non final static and non static variables?

Static variables are shared among all instances of a class. Non static variables are specific to that instance of a class. Static variable is like a global variable and is available to all methods. Non static variable is like a local variable and they can be accessed through only instance of a class.

Why should a variable be declared as static and final?

Declaring variables only as static can lead to change in their values by one or more instances of a class in which it is declared. Declaring them as static final will help you to create a CONSTANT. Only one copy of variable exists which can't be reinitialize.

Should final variables be static?

No, absolutely not - and it's not a convention. static and final are entirely different things. static means that the field relates to the type rather than any particular instance of the type. final means that the field can't change value after initial assignment (which must occur during type/instance initialization).


1 Answers

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 come without some downsides, it may not work in all cases:

In case a final field is initialized to a compile-time constant in the field declaration, changes to the final field may not be visible, since uses of that final field are replaced at compile time with the compile-time constant.

Another problem is that the specification allows aggressive optimization of final fields. Within a thread, it is permissible to reorder reads of a final field with those modifications of a final field that do not take place in the constructor. More on this is also explained in this similar question.

like image 125
Narendra Pathai Avatar answered Oct 02 '22 20:10

Narendra Pathai