可以从类定义中删除final来打破向后兼容性吗?

时间:2010-09-08 20:48:02

标签: java inheritance polymorphism backwards-compatibility final

我目前正在阅读Joshua Bloch的Effective Java,第17项是'继承的设计和文档,否则禁止它'。作者建议默认禁止继承。

默认情况下声明类final是否安全,如果需要扩展类,则在以后的版本中删除final关键字?它是否会破坏与以前版本编译的代码的向后兼容性?

如果是这样的话,看起来更安全的做法是让所有课程都成为最终版本,并且如果有良好的支持需求,则只在将来的版本中将其删除。

3 个答案:

答案 0 :(得分:10)

它既不破坏二进制也不破坏源兼容性。这就是让课程最终成为一个好主意的原因之一;改变你的想法总是可以的。

The Java Language Specification, §13.4.2 ,有关于二进制兼容性的以下内容:

  

将声明为final的类更改为不再声明final不会破坏与预先存在的二进制文件的兼容性。

我想你仍然可以构成一个可以打破程序的解释性例子;比如字节码 - 生成一个继承自所谓的final类的类,然后加载生成的类并依赖于获取VerifyError

答案 1 :(得分:2)

我对此的看法:

删除类上的final不会立即导致问题。但请考虑一下:

有一个名为AdamsFactory的最终课程,您将其更改为非最终成绩。两个月后,一位名叫迪尔伯特的新程序员加入了你的团队 他将你曾经的最终类子类化为ScottFactory,但打破了Liskov的Substitutability Principle。

然后他让你的ComicStripPrinter类使用ScottFactory而不是AdamsFactory。有些东西必然会破裂。

这让我们回到约书亚·布洛克所说的话:

如果您打算继承:请仔细设计并记录下来。如果你不打算继承,那就防止继承。

我希望我说的不是一个很大的负担。


编辑:

转到preface of Java Langauge Specification,搜索Joshua Bloch:)

答案 2 :(得分:2)

如果您正在设计类似Java Standard API的东西,数百万程序员将使用多年,是的,请像Joshua Bloch一样思考。前进演变至关重要。

99%的Java程序都没有。它们是为内部开发而开发的,API变化的影响很小,通常所有源代码都可用于重构。简单性是此类计划的关键。如果你有复杂和花哨的设计,或者你把所有时间都花在考虑最终与否,那么你就是在浪费时间。

我责备约书亚没有为他的建议设置适当的免责声明。