为什么将类定义为final可以提高JVM的性能?

从http://sites.google.com/site/gson/gson-design-document引用:

为什么Gson中的大多数课程都被标记为final?

虽然Gson通过提供可插入序列化器和反序列化器提供了一个相当可扩展的体系结构,但Gson类并不是专门devise为可扩展的。 提供非最终的类将允许用户合法地扩展Gson类,然后期望该行为在所有后续的修订中都能正常工作。 我们select通过将类标记为final来限制这种使用情况,并等待一个好的用例出现以允许可扩展性。 标记一个类最终还有一个小优点,即为Java编译器和虚拟机提供额外的优化机会。

这是为什么? [如果我猜测:JVM知道类是final的,它不维护方法覆盖表? 还有其他原因吗?]

性能有什么好处?

这是否适用于频率实例化的类(POJO?),或者适用于持有静态方法的类(实用程序类)?

定义为最终的方法在理论上也可以提高性能?

有什么影响吗?

谢谢,Maxim。

虚拟(重写)方法通常是通过某种types的表(vtable)来实现的,这个表最终是一个函数指针。 每个方法调用都有必须经过那个指针的开销。 当类标记为final时,所有的方法都不能被覆盖,并且不再需要使用表 – 这是更快的。

一些虚拟机(如HotSpot)可以更智能地做事情,并知道方法何时被覆盖,并根据需要生成更快的代码。

这里是一些关于HotSpot的更具体的信息。 还有一些一般的信息。

IBM developerWorks上的一篇旧的,显然已经不再重要的文章,其中指出:

常见的看法是最后声明类或方法使得编译器更容易内联方法调用,但是这种看法是不正确的(或者至less是极度夸大的)。

最终的类和方法在编程时会带来很大的不便 – 它们限制了您重用现有代码和扩展现有类的function的选项。 虽然有时一个class级因为一个很好的理由而最终决定,比如强制执行不变,但使用final的好处应该超过不便之处。 性能提升几乎总是损害良好的面向对象的devise原则的坏理由,而当性能提升很小或者根本不存在的时候,这确实是一个糟糕的折衷。

另请参阅另一个问题的相关答案 。 这里也讨论.Net的等价问题 。 讨论,“ 最后的方法是内联的吗? 在一个名为“ 明天什么优化没有用处 ”的问题上,这个名单就出现了。

这里有人试图描述从静态类和最终类对HotSpot内联的影响 。

还要注意, final类和final方法的效果是纠缠在一起的。 你可能会得到一些性能上的好处(再次,我没有一个好的参考)的final方法肯定,因为它可以提示JIT做内联否则做不了(或不那么简单)。 标注课程final ,您会得到相同的效果,这意味着所有的方法都会突然终止。 请注意,Sun / Oracle的人声称HotSpot通常可以使用或不使用final关键字。 课堂本身是否还有其他的影响?

作为参考,链接到最终方法和最终课程的JLS。

不知道每个特定的JVM的实现,我理论上会说,如果一个JVM知道一个指向一个对象的指针是一个指向最终types的指针,它可以做非虚函数调用(即直接与间接)到成员函数(即没有通过函数指针的间接寻址),这可能导致更快的执行。 这也可能反过来导致潜在的可能性。

将类标记为最终允许在JIT阶段进一步优化。

如果你正在调用一个非final类的虚拟方法,你不知道正确的实现是在那个类中定义的,还是你不知道的一些子类。

但是,如果你有一个最终的类的引用,你知道需要的具体实现。

考虑:

 A extends B B extends C B myInstance = null; if(someCondition) myInstance = new B(); else myInstance = new C(); myInstance.toString(); 

在这种情况下,JIT无法知道C的toString()的实现或者B的toString()的实现是否会被调用。 但是,如果B被标记为final,除B之外的任何其他实现都不可能是正确的实现

没有区别,这只是猜测。 唯一有意义的情况是像String这样的类,其中jvm以不同的方式对待它们。