20

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,

Ivan Balashov
  • 1,897
  • 1
  • 23
  • 33
  • Possible duplicate, although this one is not as specific - http://stackoverflow.com/questions/266806/is-there-any-performance-reason-to-declare-method-parameters-final-in-java/266981#266981 – Robin Aug 15 '11 at 15:59

7 Answers7

24

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.

Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • 1
    Thanks, Laurence. The **deoptimization** bit sounds pretty interesting! – Ivan Balashov Aug 15 '11 at 16:13
  • 1
    Laurence, you're saying there might be impact but rather negligible? In other words, we **should not** use final solely for performance reasons? – Ivan Balashov Aug 15 '11 at 16:32
  • 3
    @Ivan: I'm not saying "there might be impact but rather negligible". I'm saying that on modern JVMs it shouldn't really have any performance impact at all. On *some* JVMs it may have an impact, however. Certain versions of Android's VM may have issues, for example - Dalvik generally isn't as smart as Hotspot. I agree that you "should not use final solely for performance reasons", but that stems more from the fact that final has other very important uses (ie: improving readability/maintainability). Even when/if final has/had a big performance impact that wouldn't be the "sole" reason to use it. – Laurence Gonsalves Aug 17 '11 at 18:11
10

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.

Christian Semrau
  • 8,913
  • 2
  • 32
  • 39
8

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.

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
5

final is used at compile-time to accept or reject your source code as valid. It shouldn't have any run-time implications.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
5

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.

hmakholm left over Monica
  • 23,074
  • 3
  • 51
  • 73
  • Well spotted for non-private variables, Henning! =) – Ivan Balashov Aug 15 '11 at 16:04
  • And about private ones (which was the main reason of this question) I also wondered about that, but thought that compilers are smart enough marking not further assigned `private` fields as final. – Ivan Balashov Aug 15 '11 at 16:06
  • before they are passed to JVM for execution – Ivan Balashov Aug 15 '11 at 16:11
  • Neither Eclipse's (3.6.1) bytecode compiler nor javac (JDK 1.6.0) is smart enough to do that. – hmakholm left over Monica Aug 15 '11 at 16:15
  • @IvanBalashov: I don't think it's allowed. In any other class you can use reflection and `setAccessible(true)` and change the value. If the field was made `final`, then this would throw. – maaartinus Apr 20 '14 at 14:42
  • @maaartinus I guess that it is not allowed by the JLS, and therefore no compiler does that. For the runtime part: At least in JDK 1.6, after `setAccessible(true)` you can change a private final instance field, but you cannot update static final fields. – Christian Semrau Apr 22 '14 at 16:10
3

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.

Jörn Horstmann
  • 33,639
  • 11
  • 75
  • 118
  • Hands down, I do use `final` whenever possible. But sometimes the class can be modified later, and I still don't want to lose performance. I guess performance is not much an issue here – Ivan Balashov Aug 15 '11 at 16:38
1

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255