''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:'' * ''final'' hinders or prevents reuse when used to mark classes or methods. * Marking methods as ''final'' is unlikely improve the runtime efficiency of the code since the JitCompiler already has information about which methods have been overridden and which are leaves. * It's one more word somebody reading the code has to scan over. Naming constants in uppercase is very common so ''final'' is redundant. ---- ''Case for goodness:'' * ''final'' can be used to enforce security restrictions on code. * ''final'' allows you to forget about making a class suitable for inheritance. * ''final'' is the only way to indicate constants in Java. * Marking local variables as ''final'' is the only way to refer to an enclosing scope's variables from within an anonymous nested class. This is only a marginal benefit, since the runtime environment itself should handle this situation rather than forcing the programmer to declare these variables as ''final''. * The designation of ''final'' member variables provides simple design by contract semantics. For instance, if you forget to assign a final variable in a constructor the compiler will bark at you, same if you attempt to assign a value in an accessor method. It's a simple idiom which enforces good design because programmers don't have to worry the state of objects changing unless those changes are explicitly allowed. Also, final variables need to be validated once, and not upon every access (because they can't change). * JavaFinalArguments: Making parameters 'final' demonstrates that they are '''not''' changed anywhere within the method. Changing, "redefining," formal parameters during a method's run is perverse. You generally should not do it. * In a class with a significant number of methods overridden by subclasses, 'final' on a method says that "this method is not overridden by any subclass." * Making a variable definition 'final' declares that "This is the definition of this variable's value. It will not be changed anywhere else." This can make it easier to understand and change the code, as it's obvious that you don't have to look anywhere else to see if the variable's value is redefined. It isn't. ---- ''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