Question

I've heard that this is the case, but I couldn't find a definitive online source to confirm it.

Background: A colleague likes to make his local variables final. One of his reasons for doing so is performance. My contention is that Java's HotSpot Just In Time compiler will automatically detect invariant local variables, and make them final, so there is no performance benefit to doing that ourselves.

Note that I'm not asking whether it's good coding practice to make local variables final, because there are already plenty of (off-topic) SO questions about that.

EDIT: mrhobo makes a good point about optimization of the bytecode for integer literals. I should have given an example of the type of code I was talking about, with my question:

Object doSomething(Foo foo) {
    if (foo == null) {
        return null;
    }

    final Bar bar = foo.getBar();
    final Baz baz = this.bazMap.get(bar);

    return new MyObject(bar, baz);
}

Do you think the same type of optimization happens in this scenario, because bar and baz are both marked final? Or does HotSpot automatically detect that they're not changing within the scope of the method, and treat them as final anyway?

Similar Questions

Was it helpful?

Solution

To understand why final for local variables is completely uninteresting for the compiler, some background at how compilers work will be helpful. Basically no compiler operates on the source code (or bytecode) itself, instead they parse it into some kind of intermediate representation (often several different ones while applying optimizations). And pretty much every compiler I know of uses some form of static-single assignment or short SSA form for its intermediate representation.

As the name says SSA form basically means that every variable is assigned a value only once. To make this clearer, assume we have the following simple code fragment:

y = 4
x = 5
y = 6
z = x + y

In SSA form this looks something like the following then:

y_1 = 4
x_1 = 5
y_2 = 6
z_1 = y_2 + x_1

So why do we do this? Because it makes many compiler optimizations a whole lot easier (it is for example trivial to see that the first write to y can be eliminated since we never read it). So if you want you may see this as every variable already being final for the compiler.

PS: loops and branches do make this a bit more complicated, but I don't want to sidetrack the discussion too much there - the wiki article has a short explanation on how to solve those problems though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top