I couldn't understand the statement changes to the final field may not be observed
It tells that , if a final variable is declared as compile time constant then any change made in the final variable using reflection API further in program will not be visible to the program during execution.
For example consider the code given below:
import java.lang.reflect.*;
class ChangeFinal
{
private final int x = 20;
public static void change(ChangeFinal cf)
{
try
{
Class clazz = ChangeFinal.class;
Field field = clazz.getDeclaredField("x");
field.setAccessible(true);
field.set(cf , 190);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
ChangeFinal cf = new ChangeFinal();
System.out.println(cf.x);
change(cf);
System.out.println(cf.x);
}
}
The Output of the above code is:
20
20
WHY?
The answer lies in the output provided by javap -c
command for public static void main:
public static void main(java.lang.String[]);
Code:
0: new
3: dup
4: invokespecial
7: astore_1
8: getstatic
11: aload_1
12: invokevirtual
ss;
15: pop
16: bipush 20
18: invokevirtual
21: aload_1
22: invokestatic
25: getstatic
28: aload_1
29: invokevirtual
ss;
32: pop
33: bipush 20
35: invokevirtual
38: return
}
At line 16 (before changeFinal
method is called)the value of cf.x
is hardcoded to 20
. And at line 33 (after changeFinal
method is called) the value of cf.x
is again hardcoded to 20
. Therefore , Although the change in the value of final variable x
is done successfully by reflection API
during execution, but because of x
being a compile time constant it is showing its constant value 20
.