我要评分
获取效率
正确性
完整性
易理解

final Field

For the variables marked as final, the compiler and CPU must comply with the following reordering rules:

Operation of writing a final field in a constructor and the subsequent operation of assigning the reference to the constructed object to a reference variable

Operation of reading a reference to an object that contains the final field for the first time and the subsequent operation of reading the final field for the first time

The following is a write example:

public class FinalDemo {
    int i;          // Normal variable
    final int j;    // final variable
    
    static FinalDemo obj;
    
    public FinalDemo {  // Constructor
        i = 1;          // Write to the normal field.
        j = 2;          // Write to the final field.
    }
    
    public static void write() {    // Executed by write thread A
        obj = new FinalDemo();
    }
    
    public static void read() { // Executed by read thread B
        FinalDemo object = obj; // Read the object reference.
        int a = object.i;       // Read the normal field.
        int b = object.j;       // Read the final field.
    }
}

The following figure shows the execution sequence of the preceding code.

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

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