如果它没有在代码中修改,我应该声明一个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