I'm currently reading Effective Java by Joshua Bloch and Item 17 is 'Design and document for inheritance or else prohibit it'. The author suggest to prohibit inheritance by default.
Is it safe to declare classes final by default and in a later release remove the final keyword if there is a need to extend the class? Will it break backwards compatibility against code that was compiled with a previous version?
If so it appears that it is a safer bet to make all classes final and only remove it in a future release if there is a well supported demand.
Non-backward compatible changes include the following: Removing an operation. Renaming an operation. Changing the parameters of an operation, such as data type or order.
Backward compatibility (sometimes known as backwards compatibility) is a property of an operating system, product, or technology that allows for interoperability with an older legacy system, or with input designed for such a system, especially in telecommunications and computing.
Binary compatibility is an old idea that involves both hardware and software. Two computers can be considered binary compatible if they can run the same software without requiring that the application be recompiled.
It breaks neither binary nor source compatibility. That's one of the reasons it's a good idea to make classes final; it's always OK to change your mind about it.
The Java Language Specification, §13.4.2, has the following to say about binary compatibility:
Changing a class that was declared
final
to no longer be declaredfinal
does not break compatibility with pre-existing binaries.
I suppose you still could make up a construed example where it actually could break a program; like bytecode-generating a class inheriting from the supposedly final
class, and then loading that generated class and relying on getting a VerifyError
.
My thoughts on this:
Removing the final
on a class won't cause immediate problems. But consider this:
There was a final class called AdamsFactory which you change to non-final. Two months from now, a new programmer called Dilbert joins your team.
He subclasses your used-to-be-final class into ScottFactory, but breaks the Liskov's Substitutability Principle.
Then he has your ComicStripPrinter class use ScottFactory instead of AdamsFactory. Something is bound to break.
Which brings us back to what Joshua Block says:
If you intend inheritance: design it with deliberation, and document it. If you do not intend inheritance, then prevent it.
I hope what I said was not a big load-a-crap.
EDIT:
Go the the preface of Java Langauge Specification, and search for Joshua Bloch :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With