Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can removing final from a class definition break backwards compatibility?

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.

like image 963
Chazz Avatar asked Sep 08 '10 20:09

Chazz


People also ask

What are backwards incompatible changes?

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.

Is backward compatible?

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.

What is binary compatibility in Java?

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.


2 Answers

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 declared final 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.

like image 118
gustafc Avatar answered Sep 29 '22 20:09

gustafc


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 :)

like image 37
jrharshath Avatar answered Sep 29 '22 19:09

jrharshath