views:

215

answers:

6

Are Java final methods automatically inlined?

Many books says yes many books says no!!!

+1  A: 

If you mean "do they get inlined during compilation", then no, they won't.

However, static final fields sometimes can be inlined by the compiler, for example primitives and Strings.

skaffman
I think you mean to say "javac compilation", since the other event in question is also compilation.
Kevin Bourrillion
+1  A: 

I think that depends on which implementation of the JVM you are running on. Certainly, making a method final allows the compiler the option of making such an implementation tweak. But whether it does or not may also depend on other factors - e.g. what if its a huge method, etc.....

alasdairg
+7  A: 

Inlining of methods is performed by the JIT compiler, not javac.

Modern JIT compilers (including Hotspot) can often inline even non-final methods, "undoing" the optimisation appropriately if necessary. They're basically scarily clever.

In short: it entirely depends on the VM. In my opinion, you should make your methods final or not based on what produces the cleanest code rather than performance. I'm personally a fan of "design for inheritance or prohibit it" but that's a different discussion :)

Jon Skeet
Wasn't that something done by "javac -O" back in the old days?
Thorbjørn Ravn Andersen
@Thorbjørn: Not sure... I didn't *think* so, but I could be very wrong.
Jon Skeet
+1  A: 

final is more about adding semantics to a design than to tell a compiler or VM to inline something. Modern VMs inline much more than final methods alone, so this is not a good reason to use final or try to predict too much about runtime optimizations.

eljenso
+3  A: 

Interesting question, prompted me to look into it further. 2 interesting remarks I found -

  • 1 comment that automatic inlining is a bug:

Contrary to the implication of many tips, methods declared as final cannot be safely inlined by the compiler, because the method could have a non-final declaration at runtime.

To see why, suppose the compiler looks at class A and subclass B, and sub-subclass C and sees a final method in A which it inlines into C. But then at runtime the versions loaded for A and B are different and the method is not final in A, and overridden in B. Then C uses the incorrectly inlined version. T

And, a bit more authoritatively, from a sun whitepaper, writing that methods can be left virtual,

Because the Java HotSpot VM can automatically inline the vast majority of virtual method invocations, this performance penalty is dramatically reduced, and in many cases, eliminated altogether.

Here's a more direct reference on the mechanism.

Steve B.
If Hotspot discovers that has happened the inlining is undone. I believe it simply restarts the whole JIT process on all influenced classes.
Thorbjørn Ravn Andersen
A: 

Hotspot's decision of whether to inline is incredibly complicated, dependent on a plethora of considerations, but I don't think whether the method is marked "final" is one of them. The reason is that it is already aware of whether multiple implementations of that method have been loaded in the VM, so it's irrelevant to also know whether such implementations are allowed.

In any case, it's only going to be very small and simple methods that get inlined, and not even all of those.

Kevin Bourrillion