如果它没有在代码中修改,我应该声明一个java字段’final’吗?
我的问题主要是关于表现。 编译器知道更好,例如,在对象实例化之后不修改某个变量。 那么,为什么要打扰决赛呢?
我认为可能会有许多结构/逻辑原因,但从性能的角度来看呢? 有关系吗?
谢谢,
在现代 JVM中,final 不应该影响性能。 对于私有字段尤其如此,但即使对于非私有字段,JIT也可以优化非最终字段,因为它们是最终的,然后如果加载一些实际上修改字段的代码则进行去优化 。
也就是说,使用final的主要原因不是性能,而是使代码更易于维护。 通过最终制作字段,您可以减少代码中“移动部件”读取器的数量,从而更容易推理代码。
我怀疑从性能的角度来看这会很重要,但是如果您(但更可能是其他新开发人员)稍后尝试在代码中修改该字段,它仍然可能是一个好主意。 将其标记为final
将阻止您甚至编译它。
对字段使用final
也会影响线程安全性 。 Java Memory Model声明,对象的构造函数完成后,所有可以访问对象的线程都可以看到final
字段的值。 该保证类似于volatile
字段,其中任何线程始终看到当前值。 普通领域没有这样的保证。
并且,正如其他人所指出的,JIT可以对final
字段执行积极的优化,这对于正常字段来说并不容易,其中任何新加载的类都可以对字段进行写访问。
final
在编译时用于接受或拒绝您的源代码有效。 它不应该有任何运行时的影响。
如果该字段不是private
字段,则JVM将始终必须准备好在某个时间加载尚未遇到的类并开始修改它。 因此,对于那些字段,可能明确地将它们声明为final
将允许在JIT中进行更强的优化。 如果JIT一次只查看一个方法,私有字段甚至可能是这样。
另一方面, final
的局部变量不能在字节码编译中存活,因此应该没有性能影响。
对于局部变量,最终修饰符不保留在字节码中,因此不存在性能差异。 对于现场成员,性能影响更复杂。 它可能会给jit提示该字段未被修改并允许它将值缓存在寄存器中。 另一方面,final确实给出了关于字段值对其他线程的可见性的一些保证,这实际上可能减慢对象构造的速度。
性能方面我认为这是一种微观优化,其效果难以衡量。
我仍然建议尽可能使用final来澄清你对同事和未来自我的意图。
使用final
并不是对编译器或JIT的暗示。 这是对自己或维护代码的其他开发人员的暗示。 它清楚地表明类代码的其余部分假定该字段永远不会改变,这可能是一个特别重要的事情(例如,出于正确性和/或线程安全性原因)。 它还确保子类不会更改其值(如果字段protected
)。
例如,如果参与其值的所有字段都是最终的,则可以缓存该对象的hashCode
。
- java.security.AccessControlException:拒绝访问(“java.security.SecurityPermission”“authProvider.SunMSCAPI”)
- Joda时间 – 两个日期之间的所有星期一
- 使用命令行从Java调用git
- Maven和Java:目标org.codehaus.mojo的参数’mainClass’:exec-maven-plugin:1.2.1:java缺失或无效
- 使用Jquery Ajax将数据从jsp发送到struts2操作类
- JPA 2.0 / Hibernate:为什么LAZY使用“@OneToOne”开箱即用?
- jboss没有使用logback进行日志记录
- 另外运行两个线程的最佳方式?
- 是否有可实施(非理论)的方式来certificate电子邮件地址是否属于真实的电子邮件帐户?
- .NET中Servlet和Applet的通讯记录是什么?
- GLSL着色器:在两个以上纹理之间插值