views:

236

answers:

8

Why are people so emphatic about making every variable within a class "final"? I don't believe that there is any true benefit to adding final to private local variables, or really to use final for anything other than constants and passing variables into anonymous inner classes.

I'm not looking to start any sort of flame war, I just honestly want to know why this is so important to some people. Am I missing something?

+4  A: 

It marks that I'm not expecting that value to change, which is free documentation. The practice is because it clearly communicates the intent of that variable and forces the compiler to verify that. Beyond that, it allows the compiler to make optimizations.

Travis Gockel
Do you mean that you don't expect the reference of the variable to change? Are these private class or local variables?
Tim Michalski
Anything -- when someone is reading the code, they can see that the value (or reference) I am assigning on that line is what I am assigning it on that line for the duration of the scope. As far as making class member fields `final`, it forces those variables to be set in every constructor, which is a good guard against logic mistakes.
Travis Gockel
Yes, I'm good with using final to make a class immutable. A nice feature actually. What I have difficulties with is when someone uses final variables within a method.private BigDecimal myMethod(final BigDecimal money) { final MyCalc calc = new MyCalc(); return calc.doubleMyMoney(money);}I don't see the need to make MyCalc final. Does this really help garbage collection? Does it make the code more performant?
Tim Michalski
@Tim: It instructs the compiler to detect and prevent accidental assignments to the variable (which will very likely result in logic bugs). This is not only about runtime performance.
Thilo
@Tim: It also identifies the variable as a constant, which makes it easier for us mortals to grok your code--one less thing to keep track of.
Scott Smith
Moreover, the IDEs often support it, which is even better than the compiler support.
Michael Easter
+7  A: 
  1. Intent. Other people modifying your code won't change values they aren't supposed to change.

  2. Compiler optimizations can be made if the compiler knows a field's value will never change.

Also, if EVERY variable in a class is final (as you refer to in your post), then you have an immutable class (as long as you don't expose references to mutable properties) which is an excellent way to achieve thread-safety.

danben
Does it really help with optimizations? If a variable isn't changed after initialization, the compiler will determine that whether or not the variable is marked final.
Michael Burr
Yes Michael, I've heard this too. Where did you learn this? I can't seem to find any docs that break down these compiler optimizations.
Tim Michalski
If you add final to all variables, even local method variables, because you believe the reference that the variable points to shouldn't be overwritten, isn't that being a bit over protective? Bad coders will do bad things, good coders do good things. There's nothing to prevent a bad coder from being stupid and overwriting an object reference. Excessive use of "final" doesn't stop that, in fact, it probably numbs people to the real importance of using final. This is my point, I guess.
Tim Michalski
"Bad coders will do bad things, good coders do good things". Good coders still make spelling mistakes (such as assigning to the wrong variable) and love tools that can catch those.
Thilo
@Tim: No, the use of `final` *will* stop that. It is a compilation error to try to assign a variable marked `final` a second time.
Travis Gockel
'Final' is only one of the pre-reqs for immutability. For a perfectly immutable class you would also need to1. Ensure that either the class is final or all the methods you provide are final.2. All non-primitive objects and other composed objects should be deep cloned way in and way out.3. All methods that use any internal object should deep clone the attribute and then use it.You may read the details on the same at, http://azcarya.blogspot.com/2007/10/immutable-classes.html
Sandy
`final` on local variables will make any difference to the class files, so cannot help performance. It is important to distinguish between local variables and fields. / `final` wont make a reference to a mutable object into a constant.
Tom Hawtin - tackline
@Sandy - I don't think you read the part where I specified that no references to mutable properties may be exposed. This covers your cases 2 and 3.
danben
@Tom Hawtin - changed "variable" to "field" in point 2 for clarity.
danben
@Tom Hawtin - tackline: Yes, I misstated that final wouldn't prevent an object reference from being overwritten. What I should have written is that the contents of an object are still modifiable even though a variable is final. My point is that it is not a good idea to use final on any variable without a purpose specific to that field/method/class. I don't think the purpose should be compiler optimizations (thus every field is final) or to prevent a stupid developer from overwriting an object reference (thus every field is final).
Tim Michalski
I am going to mark this question as my chosen answer because it's true what danben is saying. I will add that my opinion is that people SHOULD NOT use final liberally because it means nothing when everything is final for no specific purpose (see prior comment).
Tim Michalski
A: 

I think use of final over values that are inner to a class is an overkill unless the class is probably going to be inherited. The only advantage is around the compiler optimizations, which surely may benefit.

Sandy
When you say "overkill", what do you mean? That is, what is it too much of?
danben
people are mentioning compiler optimizations, but I've heard that with recent advances in the compiler, that the final keyword doesn't help the optimizer. I haven't been able to find official documentation on this, so I'm not sure where people are getting this rumor.
Tim Michalski
Every single class variable (which makes an immutable class) and every local variable within methods. So many of the lines of code in a class start with "final". I find this very difficult to read and I'm struggling with the benefits.
Tim Michalski
@Tim: That you have to type final all over the place is not so nice (not because you are forced to type it, but because most people will not spell it out even the variable should be final). "Final" should maybe be the default for some situations (such as formal method parameters). But that's too late now.
Thilo
By overkill I meant that it is unnecessary to be written... they won't add any value. Again, making a class final and all variables final does not create a perfect immutable class, but yes, are the necessary steps to do so.
Sandy
@Thilo: I agree with your statement. Thanks.
Tim Michalski
+3  A: 

It's important because immutability is important particularly when dealing with a shared memory model. If something is immutable then it's thread safe, that makes it good enough an argument to follow as a best practice.

http://www.artima.com/intv/blochP.html

Jon
Yea, but that is irrelevant to local variables and parameters because they are only visible to the current thread.
Stephen C
Sometimes you need to make them final, sometimes you don't, depends on the situation. A best practice always has exceptions to the rule.
Jon
+2  A: 

A project I'm currently working on is setup in a way that whenever one presses "save" in Eclipse, the final modifier is added to every variable or field that is not changed in the code. And it hasn't yet hurt anybody.

Bozho
@Bozho: does Eclipse does this by default or do you need any plugin? Do you know if there's something similar for IntelliJ IDEA?
Webinator
@WizardOfOdds : no, its an ant builder, which in turn calls a custom task of the eCommerce platform we're using.
Bozho
+1  A: 

One benefit for concurrent programming which hasn't been mentioned yet:

Final fields are guaranteed to be initialized when the execution of the constructor is completed.

starblue
+1  A: 

There are many good reasons to use final, as noted elsewhere. One place where it is not worth it, IMO, is on parameters to a method. Strictly speaking, the keyword adds value here, but the value is not high enough to withstand the ugly syntax. I'd prefer to express that kind of information through unit tests.

Michael Easter
A: 

The downside, is that

annoy it is hard
annoy to read
annoy code or anything
annoy else when it all 
annoy starts in the 
annoy same way

Other than the obvious usage for creating constants and preventing subclassing/overriding, it is a personal preference in most cases since many believe the benefits of "showing programmer intent" are outweighed by the actual code readability. Many prefer a little less verbosity.

As for optimisations, that is a poor reason for using it (meaningless in many cases). It is the worst form of micro optimisation and in the days of JIT serves no purpose.

I would suggest to use it if you prefer, don't if you that is what you prefer. Since it will all come down to religious arguments in many cases, don't worry about it.

Robin