Card 08/ 10
The final Keyword on Classes, Methods and Fields
One keyword, three build failures, and a final list that can still be added to.
final means "cannot be replaced", and what that stops depends on where it is written. A final class cannot be extended, a final method cannot be overridden, and a final field cannot be assigned again once set, although the object it points at can still change.
You extend a class from a library and the build fails. You override a method and the build fails. You assign to a field in a second method and the build fails. One keyword, three different messages:
| Written on | Prevents | Still allowed |
|---|---|---|
| A class | Anything extending it | Creating instances, calling everything on it |
| A method | A subclass overriding it | Calling it, and overloading the name |
| A field | Assigning to it after it is set | Changing the object it points at |
final class Money { }
class Account {
final List<String> history = new ArrayList<>();
void log(String line) {
history.add(line); // fine
history = new ArrayList<>(); // will not compile
}
}The last row is the one that surprises people. final on a reference field freezes the address, not the object at that address. Line 7 changes the list and is legal; line 8 tries to point the field somewhere else and is not.
Reach for final on fields by default: it says the value is decided once, and the compiler will tell you if any path fails to set it. Reach for it on classes and methods deliberately, because it is a promise to everyone that this behaviour will never be replaced.
← → move through sections and cards