The use of the keyword ‘final’ should be the rule/best practice and the default behavior:
//final variable
final Amount amount = new Amount();
//final field
class Car {
final double count;
}
//final argument
void calculate (final int a)
Let’s see why:
- prevents accidental modifications
In the case of ‘simple’ types (primitives, wrappers), this is easy because we can prevent value changes. In the case of objects, we can prevent reference changes, but not to the object content. Better than nothing. In any case, it is a really big advantage:
int calculate (final int aa) {
pass(object); //compilation error: java: final parameter aa may not be assigned
internalUsage(a);
}
- clear intension
If we see ‘final’ in the code, we have a clear intention that the variable/field/ argument is read-only/cannot be modified! This is a strong assumption and simplifies the readability and understandability of the code.
- indicate an immutable class
Once in code I noticed a class with many fields. I started to analyze the use of one of the field and noticed that this field was read-only. I marked it as final. I also marked other fields as final because I realized that the compiler would detect changes. After marking all fields as final, the code was still green! It turned out that the class was immutable (all field as read-only) – the class state does not change. This is very important information as it greatly simplifies the understanding of the code and future refactorings.
We can also mark the classes and methods as final, but in this case, we use them for special purpose – class can’t be extended, method can’t be @Override’n
Summary
Use ‘final’ for variables, fields, arguments/parameters. You will see the benefits in a short time.