Here’s an interesting article that is totally, completely 180 degrees wrong. I’ve said this before, and I’ve said it again, but I’ll say it one more time:
final should be the default. Java’s mistake was not that it allowed classes to be final. It was making
final a keyword you had to explicitly request rather than making finality the default and adding a
subclassable keyword to change the default for those few classes that genuinely need to be nonfinal. The lack of finality has created a huge, brittle, dangerously breakable infrastructure in the world of Java class libraries.
The latest shot from the final-haters is a false claim that finality somehow prevents unit testing. To paraphrase Henry S. Thompson, I hate to move a direct negative, but no! There is nothing in finality that prevents unit testing, and I don’t know why people claim it does. I’ve had zero trouble testing final classes in my own work. I suppose it makes writing mock classes a little trickier, but I’m not sure that’s a bad thing. I much prefer to test the real classes and the real interactions that show what really happens rather than what the mock designer thinks will happen. Bugs aren’t always where you expect them to be. And even if finality did somehow interfere with unit testing, breaking the API to support the tests is a clear case of the tail wagging the dog. The tests exist to serve the code, not the other way around.
By way of contrast, although I’m careful to unit test subclassing for my nonfinal classes, I rarely encounter any other projects and libraries where that’s done. I’d venture to say that classes that allow their methods to be overridden rarely test that scenario in any way at all. Ditto for testing protected methods.
I will back up a little bit. It’s really only overriding methods that bothers me. I don’t have any particular objection to adding methods to a subclass. Probably the default should be to make all methods
final unless they’re explicitly tagged as overridable. If that were done, you’d rarely need
final on classes. However methods should be allowed to be overridden only after much careful thought, planning, and testing.
One final point:
final is the safe, conservative choice. Should you mark a class or method final, and later discover a need to subclass/override it, you can remove the finality without breaking anyone’s code. You cannot go the other way. Once you’ve published a class that’s non-final you have to consider the possibility that someone, somewhere is subclassing it. Marking it final now risks breaking people’s running code and working systems.
One of the principles of exteme programming is to make the simplest change that could possibly work. Final is simpler than non-final. Final commits you to less. If you need a class to be non-final, fine. But please don’t make classes non-final by default.