Should I declare a java field 'final' when if it's not modified in code?
My question is mainly about performance. The compiler knows better that, for example, some variable is NOT modified after object instantiation. So, why开发者_运维知识库 bother with final?
I presume many structural/logical reasons might come here, but speaking from the performance point of view? Does it matter?
Thanks,
In a modern JVM, final shouldn't affect performance. This is especially true for private fields, but even for non-private fields the JIT can optimize non-final fields as thought they are final, and then deoptimize if it loads some code that actually does modify the field.
That said, the main reason to use final is not performance, but to make your code more maintainable. By making fields final you are reducing the number of "moving parts" readers of your code have to think about, making it much easier to reason about the code.
Using final
for a field also has implications for thread safety. The Java Memory Model states that the values of final
fields becomes visible to all threads that can access the object as soon as the constructor of that object finishes. That guarantee is similar to volatile
fields, where any thread always sees the current value. There is no such guarantee for normal fields.
And, as others noted, the JIT can perform aggressive optimizations for final
fields, which are not so easy for normal fields, where any newly loaded class could have write accesses to the field.
I doubt it would matter from a performance point of view, but it still is probably a good idea in case you (but more likely some other new developer) later tries to modify that field in code. Having it marked as final
will prevent you from even compiling that.
final
is used at compile-time to accept or reject your source code as valid. It shouldn't have any run-time implications.
If the field is anything but private
, a JVM will always have to be prepared that a class that it has not encountered yet will at some time be loaded and start modifying it. So for those fields it is possible that explicitly declaring them final
will allow stronger optimizations in a JIT. This could even be true for private fields if the JIT is looking at a single method at a time.
On the other hand, final
on local variables does not survive bytecode compilation and so should have no performance effects.
For local variables the final modifier is not kept in the bytecode, so there can be no performance difference. For a field member the performance implications are more complicated. It might give the jit a hint that the field is not modified and allow it to cache the value in a register. On the other hand, final does give some guarantees regarding the visibility of the fields value to other threads, which might actually slow down object construction.
Performance wise I think this is a micro optimisation whose effect would be hardly measurable.
I would still recommend to use final when possible to clarify your intent to to your colleagues and your future self.
Using final
is not really a hint to the compiler or the JIT. It's a hint to yourself, or the other developers maintaining the code. It makes it clear that the rest of the class code assumes that this field never changes, which can be a particularly important thing (for correctness and/or thread-safety reasons, for example). It also makes sure that a subclass may not change its value (if the field is protected
).
The hashCode
of the object could for example be cached if all the fields participating in its value are final.
精彩评论