26

I understand how the below statement works.

for(final Animal animal : animalList){
//do some function
}

But what is the purpose of using the final keyword here ?

kosa
  • 65,990
  • 13
  • 130
  • 167
Krithika Vittal
  • 1,477
  • 2
  • 16
  • 32
  • 4
    It just means that the variable `animal` can't be reassigned e.g. `animal = new Animal(); //inside the loop code`. – Luiggi Mendoza Aug 02 '13 at 14:36
  • @Luiggi -> Will variable `animal` not be assigned a new reference on each iteration ? – Learn More Aug 02 '13 at 14:40
  • @LearnMore note the comment: *inside the loop code*. – Luiggi Mendoza Aug 02 '13 at 14:41
  • 2
    @LearnMore The entire variable is redeclared for every iteration of the loop. – Chris Bode Aug 02 '13 at 14:43
  • Thanks for response. Answers by Tala and Kan clarify this more. – Learn More Aug 02 '13 at 14:45
  • @LearnMore even if you don't mark the `Animal animal` as `final` and reassign it inside the `for` loop, the value stored in the `Collection` won't be modified since it's just a copy. With this as basis, StephenC is right by saying *It could simply be a way to avoid changing the loop variable accidentally* and also provides another reason none of the other answered considered. – Luiggi Mendoza Aug 02 '13 at 14:47

5 Answers5

36

There are two possible reasons to do this:

  • It could simply be a way to avoid changing the loop variable accidentally in the loop body. (Or to document the fact that the loop variable is not going to be changed.)

  • It could be done so that you can refer to the loop variable in an anonymous inner class. For example:

    for(final Animal animal : animalList){
        executor.submit(new Runnable(){
            public void run() {
                animal.feed();
            }
        });
    }
    

    It is a compilation error if you leave out the final in this example.

    UPDATE it is not a compilation error in Java 8 and later versions. The non-local variable is now only required to be effectively final. In simple terms, that means that the variable is not assigned to (using an assignment operator or a pre/post increment or decrement operator) after the initial declaration / initialization.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
10

Adding final keyword makes no performance difference here. It's just needed to be sure it is not reassigned in the loop.

To avoid this situation which can lead to confusions.

 for(Animal animal : animalList){
       //do some function
       animal = anotherAnimal;
       // use animal variable here
    }

You could also need to use this variable in anonymous function inside the loop

Tala
  • 8,888
  • 5
  • 34
  • 38
3

It simply means that the value of animal cannot change once it is set by the for loop. This may be required if you're going to reference animal within an anonymous class at some point in the loop.

Even if it isn't explicitly needed, it is good practice to make variables that will not change final. It can help you catch mistakes, and makes the code more self-documenting.

Chris Bode
  • 1,265
  • 7
  • 16
2

It's another java best practise.

The final declaration causes Java compilers to reject any assignments made to the loop variable.

When ever you have a chance, Declare all enhanced for statement loop variables final

simont
  • 68,704
  • 18
  • 117
  • 136
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • 1
    I don't find that as a Java best practice at all. If you think or know it is, please add a link that proves it. – Luiggi Mendoza Aug 02 '13 at 14:48
  • 2
    @LuiggiMendoza Where ever we have a chance to mark a something as `final` i'l simply go for it.Correct me if i'm wrong :) – Suresh Atta Aug 02 '13 at 14:51
  • 1
    So you think declaring the parameters on setters as `final` is a best practice at all? Also, your link doesn't provide a **real** difference between marking the variable as `final` or not, note that you can use the `continue` keyword in both examples and the behavior will be **the same**. – Luiggi Mendoza Aug 02 '13 at 14:54
  • @LuiggiMendoza The link: http://stackoverflow.com/questions/316352/why-would-one-mark-local-variables-and-method-parameters-as-final-in-java – kan Aug 02 '13 at 14:56
  • 1
    @LuiggiMendoza Yes,I believe in that statement.**where ever you have a chance** – Suresh Atta Aug 02 '13 at 14:58
  • 2
    This is "a good idea" but not "best practice". Something only qualifies as best practice when *most* practitioners (i.e. most experienced Java developers) would agree that it is the best solution. IMO, *most* Java developers would NOT agree that you should declare loop variables final "whenever you have the chance". – Stephen C Nov 28 '13 at 23:20
  • Please read [No Best Practices](https://www.satisfice.com/blog/archives/5164) ... and consider removing "best practice" from you vocabulary. – Stephen C Mar 03 '21 at 23:29
  • Also note that misunderstanding `final` is a common pitfall. `final` only locks the content of primitive types or the reference to an object. The referee object state can still mutate. – Léa Gris Apr 30 '23 at 11:01
0

The code is a syntax sugar for this equivalent code:

for (final Iterator<Animal> iterator = animals.iterator(); iterator.hasNext(); ) {
  final Animal animal = iterator.next();

}

I think it is answers the question.

kan
  • 28,279
  • 7
  • 71
  • 101