21

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,

1

7 Answers 7

26

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, Laurence. The deoptimization bit sounds pretty interesting!
Laurence, you're saying there might be impact but rather negligible? In other words, we should not use final solely for performance reasons?
@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.
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.

2 Comments

Thansk, Christian! But also @see Laurence's answer )
Christian is not only right its IMHO one of the most important reasons to use final: thread safety of which Laurence mentions nothing about.
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.

2 Comments

Thanks! But it seems that for not private fields final should have some performance impact. @see reply by Henning Makholm
@Ivan Balashov: cool! I wasn't aware of that. I wonder how significant an impact on performance it would have.
5

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

Comments

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.

6 Comments

Well spotted for non-private variables, Henning! =)
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.
before they are passed to JVM for execution
Neither Eclipse's (3.6.1) bytecode compiler nor javac (JDK 1.6.0) is smart enough to do that.
@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.
|
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.

1 Comment

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
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.