根据您将 final_修饰符应用于什么,它在java中会有不同的结果。我想知道的是,它是否_还能 帮助编译器创建更有效的字节码。我想这个问题深入到JVM如何工作,并且可能是特定于JVM的。
因此,以您的专业知识,以下任何一项对编译器有帮助吗?还是仅出于正常的Java原因而使用它们?
谢谢!
编辑:感谢您的所有答案!请注意,正如@Zohaib所建议的,我的问题是this的重复。发布前我的搜索不够好。我不会删除它,因为你们做出了很大的贡献,但是答案可以合并。除非另有说明,否则我将决定“关闭投票”系统。
如果使用final
字节码,效率不会明显提高,因为Java字节码编译器通常不会进行优化。效率奖励(如果有)将在JIT编译器1生成的本机代码中。
从理论上讲,使用会final
为JIT编译器提供提示,以帮助其进行优化。实际上,最新的HotSpot
JIT编译器可以忽略提示,从而做得更好。例如,现代的JIT编译器通常执行全局分析,以找出给定的方法调用是否是在应用程序当前加载的类的上下文中对叶方法的调用。这种分析比您的final
提示更准确,并且运行时甚至可以检测到何时加载了使分析无效的新类……并为受影响的代码重做分析和本机代码生成。
使用以下其他语义后果final
:
final
可以防止意外更改它。(并向读者表达您的意图。)final
防止在子类中重写。final
可以防止完全子类化。final
阻止子类对其进行更改。final
对线程安全有重要影响;参见JLS 17.5。在适当的情况下,这些都可以。但是,很明显,它们通过创建子类来限制重用的选项。在决定是否使用时需要考虑这一点final
。
因此,优良作法是用来final
(广义上)表达您的设计意图,并实现所需的其他语义效果。如果final
仅将其用作优化提示,那么您将不会取得太大成就。
有一些例外情况final
可能 导致某些平台上的性能有所改善。
在某些情况下,将字段声明为会final
更改字节码编译器处理该字段的方式。我在上面举了一个例子。另一个是“常量变量”的情况下(JLS 4.12.4),其中一个static final
字段的值 将被 由字节代码编译器都在当前类,并且在其它类内联,这可能会影响代码的观察到的行为。(例如,引用常量不会触发类初始化。因此,添加a final
可能会 更改类初始化的顺序。)
可以想象,将字段或局部参数声明为final
可能允许进行JIT编译器的次优优化,否则该优化将无法完成。然而,可以声明为final的任何领域 可能 也被推断为通过JIT编译器有效决赛。(尚不清楚JIT编译器实际上会执行此操作,以及是否会影响生成的本机代码。)
但是,底线保持不变。您应该使用它final
来表达设计意图,而不是作为优化提示。
1-此答案假定我们正在谈论具有良好JIT或AOT编译器的最新JVM。1)最早的Sun Java实现根本没有JIT编译器。2)早期的Android
Java实现使用的编译器在优化方面做得很差。实际上,早期的Android开发人员文档建议采取各种源代码级的微优化来弥补这一不足。此建议已被删除。
问题内容: 以下代码调用错误。我在参考资料中找不到关于此的任何信息。’=’运算符右侧缺少空格是一个错误。 可以编译此语法的任何其他组合。根据我们对Swift的了解,有人知道这是否真的是无效的语法吗? 编辑:错误响应是: 答案:这段摘录似乎回答了我的问题。我只是找不到最长的时间: 运算符周围的空白用于确定将运算符用作前缀运算符,后缀运算符还是二进制运算符。以下规则总结了此行为: 如果运算符的两边或两
问题内容: 在Linux中,尤其是在Debian或Ubuntu上,有预打包的Mingw交叉编译器可以生成Windows EXE。 但是是否有使用Clang而不是GCC的类似交叉编译器?(或有关如何建造这种野兽的说明。) 问题答案: 我编写了一个工具,可以在Linux上使用clang轻松地为Windows进行编译。检出: https //github.com/tpoechtrager/wclang。
我正在尝试实现一种检测重复文件的方法。我有一个MD5散列方法(让我们忽略MD5被破坏的事实)如下所示: 除了从< code>hashBytes中创建一个< code>string之外,我是否可以像这样简单地创建一个< code>Guid? 它仍然有效还是我会失去唯一性?
我正在尝试使用使用密码摘要模式的 Web 服务,并且我的 Java 应用程序中有这些功能来生成随机随机数、创建日期和密码摘要。我无法克服身份验证失败错误,并且文档不太清楚他们是否需要 SHA-1 或 MD5,因为它顺便提到了两者。我尝试了MD5而不是SHA-1,我得到了相同的结果。我设法通过 SoapUI 上的测试使请求工作,但我不知道该应用程序如何生成摘要/随机数。任何帮助,不胜感激。 下面是我
问题内容: 我知道Java本身没有直接的等效项,但也许是第三方? 真的很方便。当前,我想实现一个迭代器,该迭代器生成树中的所有节点,这大约是带有yield的五行代码。 问题答案: 我知道的两个选项是2007年的Aviad Ben Dov的infomancers- collections库 和2008年的Jim Jimler的YieldAdapter库 (在另一个答案中也提到了)。 两者都允许您使用
我正在处理一个电影数据集,该数据集有电影、genre和桥接表in_Genre的表。下面的查询试图查找两部电影之间的共同类型。我做了两个连接来获得流派列表,并做了一个交叉来找到常见的流派。有没有更有效率的办法? null