final
For the variables marked the final keyword, the compiler and CPU must comply with the following operations:
Operation of writing a final keyword in a constructor function and the subsequent operation of assigning the reference of the constructed object to a reference variable;
Operation of reading a reference to an object that contains the final keyword for the first time and the subsequent operation of reading the final keyword for the first time.
The following is a write example:
public class FinalDemo {
int i; // Common variable
final int j; // final variable
static FinalDemo obj;
public FinalDemo { // Constructor function
i = 1; // Write the common keyword.
j = 2; // Write the final keyword.
}
public static void write() { // Write thread A executes the instruction.
obj = new FinalDemo();
}
public static void read() { // Write thread B executes the instruction.
FinalDemo object = obj; // Read the object reference.
int a = object.i; // Read the common keyword.
int b = object.j; // Read the final keyword.
}
}
The following figure shows the execution sequence of the preceding code.

As shown in the figure, the operation of writing a common keyword is reordered outside the constructor function by the compiler, and thread B reads the uninitialized value of i. The operation of writing the final keyword is restricted in the constructor function by the reordering rule of writing the final keyword. Thread B can correctly read the initialized value of the final variable.

As shown in the figure, the operation of reading the object's common field is reordered before the operation of reading the object's reference. When the common keyword is read, the keyword has not been written by write thread A. Therefore, it is an incorrect read operation. The operation of reading the final keyword is forced to be performed after the object is referenced. In this case, the final keyword has been correctly initialized.