tags:

views:

1751

answers:

12
+19  Q: 

When to use final

I've found a couple of references (for example) that suggest using final as much as possible and I'm wondering how important that is. This is mainly in the the context of method parameters and local variables, not final methods or classes. For constants, it makes obvious sense.

On one hand, the compiler can make some optimizations and it makes the programmer's intent clearer. On the other hand, it adds verbosity and the optimizations may be trivial.

Is it something I should make an effort to remember to do?

+2  A: 

Here is a related post to look over: http://stackoverflow.com/questions/137868/using-final-modifier-whenever-applicable-in-java

mattlant
+11  A: 

Is it something I should make an effort to remember to do?

No, if you are using Eclipse, because you can configure a Save Action to automatically add these final modifiers for you. Then you get the benefits for less effort.

Peter Hilton
Great tip with the Save Action, didn't know about that.
sanity
I'm mainly considering the benefit that *final* makes the code safer from bugs by accidentally assigning to the wrong variable, rather than any optimisations that may or may not happen.
Peter Hilton
Is this really a problem for you? How often have you actually had a bug that resulted from this?
Alex Miller
+4  A: 

Well, this all depends on your style... if you LIKE seeing the final when you won't be modifying the variable, then use it. If you DON'T LIKE seeing it... then leave it out.

I personally like as little verbosity as possible, so I tend to avoid using extra keywords that aren't really necessary.

I prefer dynamic languages though, so it's probably no surprise I like to avoid verbosity.

So, I would say just pick the direction you are leaning towards and just go with it (whatever the case, try to be consistent).


As a side note, I have worked on projects that both use and don't use such a pattern, and I have seen no difference in the amount of bugs or errors... I don't think it is a pattern that will hugely improve your bug count or anything, but again it is style, and if you like expressing the intent that you won't modify it, then go ahead and use it.

Mike Stone
+1  A: 

Somewhat of a trade-off as you mention, but I prefer explicit use of something over implicit use. This will help remove some ambiguity for future maintainers of code - even if it is just you.

Sean
A: 

If you have inner (anonymous) classes, and the method needs to access variable of the containing method, you need to have that variable as final.

Other than that, what you've said is right.

anjanb
+1  A: 

The development-time benefits of "final" are at least as significant as the run-time benefits. It tells future editors of the code something about your intentions.

Marking a class "final" indicates that you've not made an effort during design or implementation of the class to handle extension gracefully. If the readers can make changes to the class, and want to remove the "final" modifier, they can do so at their own risk. It's up to them to make sure the class will handle extension well.

Marking a variable "final" (and assigning it in the constructor) is useful with dependency injection. It indicates the "collaborator" nature of the variable.

Marking a method "final" is useful in abstract classes. It clearly delineates where the extension points are.

Eric Rath
+25  A: 

Obsess over:

  • Final fields - Marking fields as final forces them to be set by end of construction, making that field reference immutable. This allows safe publication of fields and can avoid the need for synchronization on later reads. (Note that for an object reference, only the field reference is immutable - things that object reference refers to can still change and that affects the immutability.)
  • Final static fields - Although I use enums now for many of the cases where I used to use static final fields.

Consider but use judiciously:

  • Final classes - Framework/API design is the only case where I consider it.
  • Final methods - Basically same as final classes. If you're using template method patterns like crazy and marking stuff final, you're probably relying too much on inheritance and not enough on delegation.

Ignore unless feeling anal:

  • Method parameters and local variables - I RARELY do this largely because I'm lazy and I find it clutters the code. I will fully admit that marking parameters and local variables that I'm not going to modify is "righter". I wish it was the default. But it isn't and I find the code more difficult to understand with finals all over. If I'm in someone else's code, I'm not going to pull them out but if I'm writing new code I won't put them in. One exception is the case where you have to mark something final so you can access it from within an anonymous inner class.
Alex Miller
Joshua Bloch argues that all classes should be defined as final, unless they are designed for inheritance. I agree with him; I add final to every class that implement an interface (to be able to create unit tests). Also mark as final all protected/class methods, which are not going to be overridden.
Skillwired
With all due respect to Josh Bloch (and that's a considerable amount), I disagree for the general case. In the case of building an API, sure lock things down. Bui inside your own code, erecting walls that you later have to tear down is a waste of time.
Alex Miller
It's definitely not a "waste of time", specially because it costs no time at all... In an application, I normally make almost all classes `final` by default. You may not notice the benefits unless you use a truly modern Java IDE, though (ie, IDEA).
Rogerio
Ok, I'll bite. What benefits do you get in IntelliJ?
Alex Miller
IDEA has (out of the box) hundreds of code inspections, and some of those can detect unused/unnecessary code in `final` classes/methods. For example, if a final method declares to throw a checked exception but never actually throws it, IDEA will tell you that, and you can remove the exception from the `throws` clause. Sometimes, you can also find whole methods that are unused, which is detectable when they can't be overriden.
Rogerio
Eclipse has some of the same inspections (probably NetBeans too). I'll grant you this as a benefit but I'm not convinced it's a big deal.
Alex Miller
+3  A: 

If you are writing a application that someone will have to read the code after, say, 1 year, then yes, use final on variable that should not be modified all the time. By doing this, your code will be more "self-documenting" and you also reduce the chance for other developers to do silly things like using a local constant as a local temporary variable.

If you're writing some throwaway code, then, nah, don't bother to identify all the constant and make them final.

Alvin
+1  A: 

I will use final as much as I can. Doing so will flag if you unintentionally change the field. I also set Method parameters to final. Doing so I have caught several bug from code I have taken over when they try to 'set' a parameter forgetting Java passes by value.

Javamann
+1  A: 

It's not clear from the question whether this is obvious, but making a method parameter final affects only the body of the method. It does NOT convey any interesting information about the method's intentions to the invoker. The object being passed in can still be mutated within the method (finals are not consts), and the scope of the variable is within the method.

To answer your precise question, I wouldn't bother making an instance or local variable (including method parameters) final unless the code required it (e.g. the variable is referenced from an inner class), or to clarify some really complicated logic.

For instance variables, I would make them final if they are logically constants.

ykaganovich
+2  A: 

I've found marking method parameters and locals as final is useful as a refactoring aid when the method in question is an incomprehensible mess several pages long. Sprinkle final liberally, see what "cannot assign to final variable" errors the compiler (or your IDE) throws up, and you just might discover why the variable called "data" ends up null even though several (out of date) comments swear that can't happen.

Then you can fix some of the errors by replacing the reused variables with new variables declared closer to the point of use. Then you find you can wrap whole parts of the method in scoping braces, and suddenly you're one IDE keypress away from "Extract Method" and your monster just got more comprehensible.

If your method is not already an unmaintainable wreck, I guess there might be value in making stuff final to discourage people from turning it into said wreck; but if it's a short method (see: not unmaintainable) then you risk adding a lot of verbosity. In particular, Java function signatures are hard enough to fit into 80 characters as it is without adding six more per argument!

Sam Stokes
A: 

It is useful in parameters to avoid change the parameter value by accident and introduce a subtle bug. I use to ignore this recommendation but after spending some 4 hrs. in a horrible method ( with hundreds of lines of code and multiple fors, nested ifs and all sort of bad practices ) I would recommend you to do it.

 public int processSomethingCritical( final int x, final int y ){
 // hundreds of lines here 
     // for loop here...
         int x2 = 0;
        x++; // bug aarrgg...
 // hundreds of lines there
 // if( x == 0 ) { ...

 }

Of course in a perfect world this wouldn't happen, but.. well.. sometimes you have to support others code. :(

OscarRyz
This method has more serious issues than missing final. It's pretty uncommon, although not impossible, that there's a good reason for a method to be so cluttered that these sorts of errors would occur. A little thought put into variable names would go a long way toward accidents like this.
ykaganovich