final, final, final: Your Thoughts?

Java gurus: Should we declare method parameters and local variables final?

Enlighten me…


15 Responses to “final, final, final: Your Thoughts?”

Yes, as a way of changing the way you think. Once that change has happened, feel free to leave final off your unmutated variables!

Until Java supports tail-call elimination, you still need to mutate variables sometimes.

Fred Says:

Just an Anecdote:
I once optimize a Java framework for Value Object on JDK 1.4.2. Adding final to critical fields and methods was a huge performance boost (sometimes 50%).
When I applied those changes to 1.5 and above, well… it did improve but not impressive at all (in 1.6 it was 5% I think).
So, today it’s important for design (don’t override this or that), but for performance, you can wait ;-)

CodeToJoy Says:

I’ve wondered this one too…

+1 on local variables

-1 on method params

IMHO, final local vars increases readability/intent. I can mentally “not worry” about those vars.

For some reason, that phenomenon doesn’t happen for method params. The “final” just becomes harsh noise.

Dan Lewis Says:

IntelliJ 7 has an inspection that looks for method parameters and local variables that are candidates for the final keyword, and will “correct” those declarations with the final keyword. While I personally like to do this, I can’t point to a situation where this helped me, and it tends to annoy other developers who think final clutters things up. That makes me like to do it, but I am evil that way.

This can safely be filed away in the “dogma” filing cabinet. It isn’t going to have a big effect either way. It’s the right thing to do, but I can’t make a very convincing argument.

No, because it’s more clutter and Java is has too many annotations as it is. If you can’t tell at a glance whether a local variable is effectively final or not, your method is too long.

I think final is useful not only to enforce certain behaviors (immutability), but also to indicate what type of code you’re working with — see Reg Braithwaite’s recent post on coding conventions (http://weblog.raganwald.com/2007/11/programming-conventions-as-signals.html). Even though a final object can still be modified thru mutators, knowing that I’m passing in ‘final’ parameters indicates to me that the method I’m invoking won’t screw with my objects, that the side-effects will be limited to none.

Doug Says:

Definitely a style issue rather than a best practices issue. Personally, I prefer to reserve the “final” notation for those parameters and variables that will be accessed from an inner/nested class.

I do use “final” quite a bit on fields, though. It’s good to know which fields are mutable state and which aren’t. Also, I’m not at all shy about making final fields public rather than create getters for them.

Jesse Says:

I rarely redefine stuff, so final feels like unnecessary cruft. I like to the signal-to-noise ratio as high as possible in my code.

Alex Miler Says:

I’ve tried both for a while. I find using final in method parameters and local variables to just be way too annoying. I would much prefer it if “final” was the default and you had to mark the ones that can be changed as “mutable”. But since that’s an alternate dimension, I say none.

Sometimes I mark method parameters in the case where some are being modified and some are not to indicate which are the “input” and which are the “inout” or “output”.

However, I believe it’s highly worth marking object fields as final and I strive to accurately label immutability there and hopefully to mark everything as immutable if possible.

Phil Says:

Yes, because it prevents this typo:

private int value = …

public void setValue(int value){
value = value; //oops, forgot this
}

This is a trivial example, there there are more complex examples where you accidentally assign to variable you meant to retrieve a value from.

As someone mentioned above, I think the performance gain is no longer there because the compiler is better about determining if the variable is mutated or not and doing the appropriate optimizations if it isn’t.

I look at it sort of like Override– most of the time it doesn’t matter, but the time you leave it out will be the time you spend two hours trying to figure out why your method isn’t being called because you put the wrong generified type on it… say, like this morning.

Gordon Says:

I use final for - of course - nested classes btw faking/mocking/stubing class/object-behaviour during unit-testing (no other chance) within some kind of fake/mock/stub-creational methods.

Sometimes I use final on production code if I know myself: remindering me not to change the input properties (next difficulty: what is the second best parameter name?!). These situations are very rare and more of the kind of syntactic sugar.

I ALWAYS use the final keyword for JUnit test-methods (have thought about it long time): Just be be sure not no override a testcase- and/or setup-method in a subclass (of a fixture).

Gordon

Kirk Says:

Not against final but it does breaks the possibility for extending so it should be used with care.

Sheesh, it’s nice to see that at least a _couple_ people in there actually understood the question!

The case mentioned by Phil happened to me _twice_ in ten years of practice. If there is no performance gain, I find that using ‘final’ is like going against the coding practice of the majority. When a newbie joins your group you will _also_ have to teach him when-and-when-not and get mad when he misuses the annotation.

My learning curve is high enough as it is, thanks.

Eric Burke Says:

C’mon, guys, where are your Gravatars???

Leave a Reply