Java Final Considered Evil

Suggest we change the name to SealedClassesConsideredEvil? or similar - this is not a Java-only issue.

In the last week, I've come across two programmers and a SourceForge project that believe the Java final keyword should be used as liberally as possible. I believe final should be ConsideredHarmful if not downright evil.


Case for evilness:


Case for goodness:


Thoughts on using final

I actually try to use final more rather than less, but only at the variable level, never at the class or method level. -- AnonymousDonor

I've taken to using 'final' in just about every place where it's possible to do so. What it reveals is that those things that are not 'final' require special treatment.

And does it stop me from changing variables or overriding methods? No. It's remarkably easy to remove the 'final' keyword whenever it becomes inconvenient. -- JeffGrigg

I'm with Jeff on this. I will often declare a class 'final' to prevent me or anyone else from casually subclassing it. The extra bit of friction created -- the need to go remove the 'final' keyword -- often prompts the person doing it to do a quick reality check with themselves and/or other folks on their team. They can verify the proposed subclassing is an okay thing to do and a good approach to whatever problem is at hand (often it isn't). -- AnonymousDonor

(Of course, if you are writing code which will be distributed without source code outside your team, there are lots of further things to consider. In that situation I expect I would use final less, when declaring classes.) -- the same AnonymousDonor


The Java final keyword is overloaded, having a few different and unrelated effects, leading to some confusion over whether it is good or bad. The C++ equivalent of this is ConstCorrectness (for non-modifiability) and making constructors private (to prevent deriving subclasses). I'd agree that making data members, parameters, and variables final is a great idea, and that making classes final is evil. --KrisJohnson

Seems a little silly to say that making a class final is evil. You should make the class final if it should not be subclassed. Seems simple to me. If it can be subclassed, don't make it final. -- RobertDiFalco

I wouldn't call 'java.lang.Math' evil. (I wouldn't call it object-oriented either. But I wouldn't call it evil. I'd call it a namespace; a package of reusable procedural functions.)

I'm not sure I'd call 'java.lang.Integer' evil. But I'd call it annoying and short-sighted that they're 'final'. (In the SmalltalkLanguage, I've extended 'string', so I don't see why this shouldn't be allowed in Java.) -- JeffGrigg

I meant to say "a general policy of making all classes without subclasses final is evil". Obviously, if there is a good reason for sealing a class, then one should do so. But doing so just because you haven't created any subclasses yet is probably not helpful and is probably going to be very annoying for somebody. I think this is a good exception to the rule of using final "every place where it's possible to do so". --KrisJohnson

I agree. In the cases where it is easy for someone to remove final, generally you're in a team and you talk often enough for final to seem really poor as a communication device. In the cases where it is hard to remove final you've effectively reduced your user's options unilaterally. As a user of frameworks, it always feels like trespass to me. -- MichaelFeathers


It's the only way to force your subclass to call your superclass methods.

 interface Foo { Bar foo(); }

abstract class Bar implements Foo { abstract Bar subclass_foo() {}

final Bar foo() { do_initialisation(); return subclass_foo(); } }

This is probably the _right_ way to have a final class: provide an interface to it, and only refer to the final class/class with final method when it really matters (i.e., the 'security concerns' where the constantness of Strings matter, for instance). I often make whole boatloads of abstract classes' methods final, with a very few well-placed abstract methods. This keeps the client from upsetting what might be a delicate web of logic (unavoided due to the language); it tells them that if they _really_ need to implement those methods, perhaps they'd be better of with their own implementation where there aren't any surprises lurking in the implementation. --WilliamUnderwood

This is a fantastic way to tell future maintenance programmers that you know better than them and have anticipated their every future need and deemed them irrelavent.


CategoryJava CategoryEvil


EditText of this page (last edited May 24, 2004) or FindPage with title or text search