Should I declare a java field 'final' when if it's not modified in code?

前端 未结 7 2007
终归单人心
终归单人心 2020-12-15 21:06

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?

相关标签:
7条回答
  • 2020-12-15 21:18

    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.

    0 讨论(0)
  • 2020-12-15 21:19

    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.

    0 讨论(0)
  • 2020-12-15 21:19

    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.

    0 讨论(0)
  • 2020-12-15 21:21

    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.

    0 讨论(0)
  • 2020-12-15 21:26

    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.

    0 讨论(0)
  • 2020-12-15 21:29

    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.

    0 讨论(0)
提交回复
热议问题