Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

While I understand what the final keyword is used for in the context of classes and methods as well as the intent of its use for in regards to variables; however, the project I just started working on seems to have an excessive number of them and I'm curious as to the logic behind it.

The following snippet of code is just a short example as I don't see much point in the final keyword for the key and value variables:

private <K, V> Collection<V> getValuesForKeys(
    final Map<K, V> map, final Collection<K> keys) 
{
    final Collection<V> values = new ArrayList<V>(keys.size());
    for (final K key : keys) {
        final V value = map.get(key);
        if (value != null) {
            values.add(value);
        }
    }
    return values;
}

I have been doing a bit of reading the usage through articles I have found via Google; however, does the pattern really do things such as help the compiler optimize the code?

share|improve this question

marked as duplicate by gnat, Corbin March, Yusubov, Kilian Foth, jmo21 Aug 20 '13 at 7:52

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Just throwing this out there - but I've worked on projects where its part of the convention to use final wherever appropriate, so I usually setup eclipse or netbeans to add them to the save actions for the file. That might be why they seem "excessive" - they always do to me too. Do I really need to worry if a reference is immutable in the two lines where it is initialized, used, and discarded? –  Steve Jackson Aug 4 '11 at 19:58
1  
steve-yegge.blogspot.com/2010/07/… –  Job Aug 4 '11 at 21:39
    
final tells the reader that this variable never changes. This is important when reading code as you know when you need to know the value of the variale that it is the same as in the initial assignment and do not have to parse all the code in between to see if the variable is assigned again with something else. See stackoverflow.com/q/316352/53897 –  user1249 Aug 4 '11 at 22:11
    
@Jonas, wrote an answer at programmers.stackexchange.com/questions/98691/… –  user1249 Aug 8 '11 at 17:18
1  
Strongly related: programmers.stackexchange.com/questions/48413/… –  Oak Aug 8 '11 at 18:01

7 Answers 7

up vote 38 down vote accepted
+100

There are many references suggesting a liberal use of final. The Java Language Specification even has a section on final variables. Various rules in static analysis tools also support this - PMD even has a number of rules to detect when final can be used. The pages that I linked to provide a number of points as to what final does and why you should use it liberally.

For me, the liberal use of final accomplished two things in most code, and these are probably the things that drove the author of your code sample to use it:

  1. It makes the intent of the code much more clear, and leads to self-documenting code. Using final prevents the value of a primitive object from changing or a new object being made and overwriting an existing object. If there's no need to change the value of a variable and someone does, the IDE and/or compiler will provide a warning. The developer must either fix the problem or explicitly remove the final modifier from the variable. Either way, thought is necessary to ensure the intended outcome is achieved.

  2. Depending on your code, it serves as a hint for the compiler to potenitally enable optimizations. This has nothing to do with compile time, but what the compiler can do during compilation. It's also not guaranteed to do anything. However, signaling the compiler that the value of this variable or the object referred to by this variable will never change could potentially allow for performance optimizations.

There are other advantages as well, related to concurrency. When applied at a class or method level, having to do with ensuring what can be overridden or inherited. However, these are beyond the scope of your code sample. Again, the articles I linked to go far more in-depth into how you can apply final.

The only way to be sure why the author of the code decided to use final is to find him and ask him.

share|improve this answer
24  
Scala was smart to make val (for an immutable variable) and var (for a mutable one) exactly the same length to type. –  Ken Bloom Aug 4 '11 at 23:46
9  
The ability to express intent through language semantics rather than flimsey comments is a key to good language design (IMO) –  Loki Astari Aug 8 '11 at 17:56

The principle benefits of "final" in my mind are two-fold:

  • Final variables are "safer" than non-final variables, because once they are bound there is never a question about what their current state is.
  • Because of the above, making a variable final relieves the programmer of excess mental juggling - he/she doesn't have to scan through the code to see if the variable has changed. This happy state-of-affairs will be familiar to anyone who has spent any time in a functional-language setting.

As for this specific example, it may be that the programmer picked up the "final" habit and just applies the "final" keyword everywhere as a matter of course. (I am skeptical of the notion that the final keyword would help the compiler when talking about individual assignments — surely it doesn't need the help to determine only one assignment took place?)

I'm of the opinion that Java got it backwards — there should be no "final" keyword for variables, everything should be "final" by default, and if you want a mutable variable you should have to add a keyword for that ("var" or some such). (As another commenter mentioned, scala has two keywords — "val" and "var" for final and non-final variables, respectively - I'll take it).

share|improve this answer
2  
+1 agree with the final should have been the other way around. Unfortunately they wanted C syntax. –  user1249 Aug 8 '11 at 17:23
1  
Definitely agree that it should have been the other way around. My coding style uses lots of stuff that could be final, but I don't make it final because it makes the code look cluttered and messy. I try to keep methods short so that it's obvious what's going on, though. –  Adam Jaskiewicz Aug 8 '11 at 17:44
    
+1 for "I'm of the opinion that Java got it backwards..." - couldn't agree more –  reevesy Sep 14 at 0:44

In Java the only place to my knowledge where the final keyword is required is to make a variable reliably available to an anonymous class (since the compiler does some trickery under the covers requiring that this value cannot change).

It is - to my knowledge - a myth that the final keyword allows the Java compiler to optimize code, as all optimizations that matter happen in the JIT part of the runtime.

It is therefore a matter of taste. There is, however, one very significant benefit for using lots of finals, namely to make the code easier to read for future maintainers.

Marking a variable as final tells the reader that this variable never, ever changes when assigned. This is very important when reading code as you know when you need to know the value of the variable that it is the same as in the initial assignment and do not have to mentally parse all the code in between to see if the variable is assigned again with something else.

Also if you see that a variable is not marked with final you know that it will be changed further on! This is an extremely important piece of information that can be conveyed to the reader simply by having five characters missing.

Anything that can help the maintainer do his/her job faster and more reliably mean that the application is cheaper to maintain! In other words, final saves real money.

Note: Eclipse has a "source clean-up" option which can insert finals where possible. This might be helpful both for writing new code, and for maintaining old (insert finals, if some are missing the variable is changed after initial assignment). My gut feeling is that this is what the original author discovered and decided to use.

The subject is discussed further at http://stackoverflow.com/q/316352/53897

share|improve this answer
2  
final, though not in the case of an instance variable, does sometimes prevent the overhead of dynamic binding by inlining methods. This will avoid branching on the CPU. In Java, polymorphism is supported unless you specify final whereas in c++ and c#, it is not unless you specify virtual. Not that that really matters on modern CPU's. Anyways, you are correct that it does not optimize instance variables. –  Jonathan Henson Aug 11 '11 at 18:42
1  
Modern JVM's can do this automatically without having to hint with final. –  user1249 Jan 9 '12 at 14:57

I think the answer to this is simpler than others suggest. It's not about intent, or design. A good while ago, it was true that adding final in some places (particularly, for methods and classes) allowed the JVM to optimise more aggressively. As a result, some people went berserk and put final literally everywhere to try and get their code to go faster.

I should add that it's not the compiler, but the JVM which does the optimisation. Furthermore, I doubt putting final on a local variable would ever have made any difference to performance.

Finally, using final probably wouldn't make much difference these days as JVM optimisations have advanced somewhat.

share|improve this answer
1  
"I doubt putting final on a local variable would ever have made any difference to performance" -- Most JVMs I'm aware of (a bit dated in my knowledge) use a Tree-SSA data structure as an intermediate representation. All assignments spawn a new SSA tree, so this is a safe assumption. By the time they hit the optimization, they don't even know which variable reference it referred back to. –  ccoakley Aug 8 '11 at 20:30
1  
"I doubt" -> "I haven't measured..." –  user1249 Jan 9 '12 at 14:55
1  
-1 for speculation as fact –  Jarrod Roberson Feb 10 at 7:12

It looks to me like the final keyword is being used in this context to make an immutable collection. Immutable collections are simpler to reason about and safer to use in programs requiring concurrency (multiple threads).

share|improve this answer
10  
But it isn't immutable; only the reference is immutable. You can still modify the contents of the collection, but you can't reassign the reference to point at another collection. –  Adam Jaskiewicz Aug 4 '11 at 20:18
    
@Adam: The elements are also marked final –  Robert Harvey Aug 4 '11 at 20:45
4  
But the collection itself is still mutable. If another thread holds a pointer to the same map that is being passed into getValuesForKeys, it can add and remove elements at will. Likewise with whatever Collection keys is pointing to can be modified in another thread, likely causing a ConcurrentModificationException to be thrown by the for-each. –  Adam Jaskiewicz Aug 4 '11 at 21:08
    
@Adam: Ah, I see what you mean. –  Robert Harvey Aug 4 '11 at 21:16
    
If you truly want an unmodifiable collection, you can use Collections.unmodifiableXXX methods –  nerdytenor Aug 5 '11 at 5:57

In a class, final prevents it from being extended. It also keeps a user from overriding a method in a subclass. You would do this, either to protect the functionality of your class or to keep someone from tampering with the basic way it works. It is also more efficient once compiled--I don't know exactly how at the moment, I just know that it is.

You would use it for a variable as shorthand for a value. This is the java replacement for the c/c++ #define name value or the const keyword. The main reason you do this is to increase readability and to save yourself the trouble of having to write a value multiple times in your code. Especially because when you want to change that value, you would have to change it everywhere. The final keyword ensures that you couldn't accidentally change its value at another place in your code.

It does seem to be excessive in the code you posted above.

Also, it obviously is different from c++ in the respect that a const value can't be changed inside a method, while this one obviously is being changed.

In addition, once a variable is set to final it ensures thread safety as it is impossible to write to the value.

share|improve this answer
2  
Most of what you wrote has nothing to do with the use of final in the example code. Also, the sentence about changing values makes no sense - the value of the variable isn't being changed. –  Thomas Owens Aug 4 '11 at 18:45
    
@Thomas the values collection is having its state altered when you call values.add –  Jonathan Henson Aug 4 '11 at 18:46
    
I believe that's acceptable. However, you can not change the object to which the variable refers to. The memory address of the object never changes. –  Thomas Owens Aug 4 '11 at 18:47
    
@Thomas "As such, can anyone provide some insight as to the value of the final keyword and fairly excessive use of it in code?" I took this to mean that you wanted a more generic answer than just the code you posted. –  Jonathan Henson Aug 4 '11 at 18:48
2  
-1. Very little here answers the explicit questions posed by the asker. He clearly says he knows what final is, but wants to know why it is being used in this context. –  Thomas Owens Aug 4 '11 at 19:09

Final method parameters

I like final method parameters, because they help to prevent silly mistakes like changing which object is reference by a String parameter.

Final method locals

I don't have a strong opinion about this technique. It prevents the reassignment of the variable mid method, but that is not always a bad thing.

Final loop counter

Again, no strong opinion about this (final K key).

Final variables inside loops

Declaring a final variable inside a loop (ex. final V value) guarantees that a value is pushed and popped off each time through the loop. This is not the brightest of techniques. I tend to go further and say "this is a technique for monkies, not for software developers", but I tend to have strong opinions.

Things not mentioned

I like final classes. If a class is not designed to be extended, I make it final.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.