My question is mainly about performance. The compiler knows better that, for example, some variable is NOT modified after object instantiation. So, why bother with final?
Using final
for a field also has implications for thread safety. The Java Memory Model states that the values of final
fields becomes visible to all threads that can access the object as soon as the constructor of that object finishes. That guarantee is similar to volatile
fields, where any thread always sees the current value. There is no such guarantee for normal fields.
And, as others noted, the JIT can perform aggressive optimizations for final
fields, which are not so easy for normal fields, where any newly loaded class could have write accesses to the field.