Sponsored Link •
Bill Venners: I wanted to talk about your recommendation that we document for inheritance or disallow it.
Josh Bloch: I should come clean right up front. That was a deliberate overstatement. If you look at our APIs, you'll see that there are a bunch of them that are neither designed for inheritance nor do they disallow it. For example,
Hashtable isn't designed for inheritance, but doesn't disallow it. And in fact, people do subclass it. They do override methods, and they do produce garbage.
The statement was a reaction to stuff that I'd seen, but I didn't start really putting it into practice until recently. Realistically, I don't expect people will start designing for inheritance or disallowing it outright, but I hope they will start thinking in these terms. At least they will start disallowing untrammeled inheritance, where you can override anything and produce complete garbage. I hope the advice will cause people to write more final classes, more immutable classes, generally safer classes. But I don't expect that as of tomorrow, everybody will start designing for inheritance or disallowing it.
Bill Venners: I kind of got from reading your book that this was something that you'd come to more recently. It made sense to me, but I had really never thought about it before. When I first read about final classes in Gosling and Arnold's The Java Programming Language book, it said, "Be careful. Making classes final is an extremely severe restriction on clients, and you should only do it for security reasons." And so, I think I still kind of have that mindset. I am sheepish about making classes final because it seems so drastic.
Josh Bloch: You don't need that mindset anymore. My view is you can always add something, but you can't take it away. Make it final. If somebody really needs to subclass it, they will call you. Listen to their argument. Find out if it's legitimate. If it is, in the next release you can take out the final. In terms of binary compatibility, it is not something that you have to live with forever. You can take something that was final and make it non-final. If you had no public constructors, you can add a public constructor. Or if you actually labeled the class final, you can remove the access modifier. If you look at the binary compatibility chapter of the JLS (Chapter 13), you will see that you have not hurt binary compatibility by adding extendibility in a later release.
Bill Venners: Well, if a class is
Serializable I think it will often be impractical to remove final in a later version of the class. Let's say you and I are two VMs on a network, and you have version one of a class, which is final. I have version two of that class, in which final has been taken away, plus a subclass of the now non-final class. If I attempt to serialize and send you an instance of the subclass, it won't deserialize on your side. Because on your side the class exists, but at version one, which is final.
Josh Bloch: Yep.