【问题标题】:Should methods be declared as final if they are not overridden?如果方法没有被覆盖,是否应该将它们声明为 final?
【发布时间】:2017-02-24 13:56:20
【问题描述】:

我读到将方法声明为 final 会提高性能。那么,将不希望被覆盖的方法声明为 final 是否有意义?我的问题是关于性能的改进以及此类使用的任何相关缺点。

【问题讨论】:

  • 我阅读了那个问题和答案。其中一些暗示最终声明可能有助于提高性能,但不要鼓励(或阻止)它的使用,除非您的目标是明确停止覆盖。我想知道为什么这不被视为标准做法。性能提升是否太小而不值得,或者有一些附带的缺点。
  • "预计不会被覆盖的方法" - 您只是不期望它们被覆盖还是您不想要它们被覆盖被覆盖?如果后者则使用final,如果前者则考虑从长远来看有多少期望被证明是错误的,然后自己决定(正如其他人已经说过的:单独的性能原因可能无效或至少影响可以忽略不计)
  • 我说的是预期。但是,其他答案让我相信性能提升可以忽略不计。

标签: java oop object methods final


【解决方案1】:

我读到将方法声明为 final 可以提高性能。

这对于最近的 HotSpot JIT 编译器是不正确的。我的理解是,JIT 编译器会查看所有当前加载的类,以确定它编译的每个方法是否有任何覆盖。如果没有找到,则 JIT 编译器将该方法视为 final1

因此,将方法 final 声明为优化没有意义。

(这可能不适用于所有 Java 平台;例如,具有原始 JIT 编译器的非 HotSpot 平台。)


在方法上更好地使用final 是当您希望/需要通过子类化来禁止您的类的某些类型的扩展 时。是否/何时这样做是一个见仁见智的问题。我当然不会“理所当然地”这样做。


1 - 如果动态加载引入了一个新的子类,该子类重载了以前未被覆盖的方法,HotSpot JIT 编译器甚至会重新编译以前编译的类。

【讨论】:

  • 使用 'final' 可能会通过不强制编译器查看所有类来节省时间。这对性能有帮助吗?
  • 节省的费用微乎其微。不是值得优化的东西。当没有真正需要时,您必须考虑声明方法final 的危害。它会使代码重用变得更加困难。
  • 更有害的是编写不是final 的方法而不是不小心和计划。 Effective Java,Josh Bloch:第 17 条:为继承设计和记录,否则禁止它。
  • @LewBloch - “是否/何时执行这是一个见仁见智的问题” - Stephen C,StackOverflow,2017 :-)
  • 这是一个设计问题,而不是意见。作者的选择是肯定的。这是关于作者对课程的意图。
【解决方案2】:

那么,声明不期望的方法是否有意义? 最终被覆盖?

我不相信。 final 关键字表示此方法不能 被覆盖(例如出于安全原因),而不是原始开发人员不希望您想要覆盖它。这将是非常冒昧的,并且肯定会降低 API 的可扩展性。

正如另一个答案中提到的,我不认为它会对性能产生任何影响,如果确实如此,你就不会注意到!

【讨论】:

  • “降低 API 的可扩展性”通常是正确的做法,当然不是“自以为是”,只是好的工程。
  • 恐怕我们将不得不同意不同意这一点。在我看来,能够覆盖方法是 OO 设计中最有用和最核心的原则之一。我还没有遇到过这种情况导致问题的情况。如果是这样,那么“最终”就是解决方案。
  • 语言支持继承并不意味着继承总是正确的。 Effective Java 说,“更喜欢组合而不是继承”。同样,方法不应该总是可覆盖的。我没有说过能够覆盖方法是不好的。确实,通常情况下,使方法可覆盖并不是正确的决定。您应该只在有意义的情况下使方法可重写,并且您可以承担可遗传性的责任。
  • Effective Java 确实这么说,但是我不同意我读到的所有内容。我同意,继承并不总是 最好的 解决方案,但如果您按照原始问题中提到的方法设计 API,那么您就是在声明继承 从不 正确的解决方案.
猜你喜欢
  • 1970-01-01
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
相关资源
最近更新 更多