Card 08/ 10
All 10 cards
GotchaDifficulty: Advanced1 min
What final Stops, on a Class, a Method and a Field
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.