Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is declaration of the variable required inside a for-each loop in java

The usual form the of for each loop is this:

for(Foo bar: bars){     bar.doThings(); } 

But if I want to retain bar until after the loop, I can not use the for each loop:

Foo bar = null; // - Syntax error on token "bar", Identifier expected after this token for(bar: bars){      if(bar.condition())         break; } bar.doThings(); 

The for loop gets the syntax error mentioned above.

Why is this? I'm not interested in workarounds, but just curious to the considerations behind this limitation.

In contrast, with an ordinary for loop, the variable can be declared outside or not at all...

int i = 1; for(;i<max;i++){     for(;;){         // Do things     } } 
like image 343
Stim Avatar asked May 26 '11 09:05

Stim


People also ask

Why is a variable declaration required?

Some languages require you to declare variables, in order to explicitly allocate memory for it (location and/or size). Some languages do this memory-allocation for you.

Why is it important to declare a variable in Java?

Declaring a variable helps the Java compiler to know the type of value that we want to store in the variable The compiler uses this information to allocate proper memory for storing the variable.

How do you declare a variable in a foreach loop in Java?

It starts with the keyword for like a normal for-loop. Instead of declaring and initializing a loop counter variable, you declare a variable that is the same type as the base type of the array, followed by a colon, which is then followed by the array name.

Do you have to initialize a variable in a for loop?

In short, you are right to do it. Note however that the variable is not supposed to retain its value between each loop. In such case, you may need to initialize it every time.


2 Answers

This is a good question and I would be happy to see some in-depth answer. However, the official documentation says:

These shortcomings were known by the designers, who made a conscious decision to go with a clean, simple construct that would cover the great majority of cases.

The great majority of cases is the answer for me.

On a side note, personally, I think that foreach loop in Java is just a nice syntax for a standard iterator loop. So, the compiler creates the iterator for the structure and uses the variable to get the value for current iteration. To ensure that the variable has been initialised you need to declare it for the scope of loop (and I think this prevents the variable from being used somewhere else, e.g. in another thread). Because of that, you cannot use the variable after the loop. But, this is just my opinion and I would be very happy to hear from someone who knows it better. :)

Edit Here is an interesting article about foreach loops in Java.

Another edit I analysed (with jclasslib the bytecode of these methods:

 private static void testForEach(ArrayList<String> als) {   for(String s: als)     System.out.println(s);  }   private static void testIterator(ArrayList<String> als) {   for(Iterator<String> is = als.iterator(); is.hasNext();) {    String s = is.next();    System.out.println(s);   }   } 

Both methods are represented by the same bytecode:

 0 aload_0  1 invokevirtual #2 <java/util/ArrayList.iterator>  4 astore_1  5 aload_1  6 invokeinterface #3 <java/util/Iterator.hasNext> count 1 11 ifeq 34 (+23) 14 aload_1 15 invokeinterface #4 <java/util/Iterator.next> count 1 20 checkcast #5 <java/lang/String> 23 astore_2 24 getstatic #6 <java/lang/System.out> 27 aload_2 28 invokevirtual #7 <java/io/PrintStream.println> 31 goto 5 (-26) 34 return 

The difference is in line 1, the latter method uses invokevirtual #8. However, both invocations result in calling the same method of Iterator. So, it seems that foreach is nothing more than a syntactic sugar that the compiler just translates into a predefined construct, just as the documentation says. This does not answer the question why it is the way it is. I though this is just interesting and might be worth to know, in the context of the discussion.

like image 160
Miki Avatar answered Oct 18 '22 00:10

Miki


I guess they just wanted to promote "good practices": from the Java language guide:

These shortcomings were known by the designers, who made a conscious decision to go with a clean, simple construct that would cover the great majority of cases.

As we know, the behaviour you are asking for can be simulated by just expanding the for-each loop to the old iterator - based style, and probably they just thought its Good Enough.

like image 34
Waldheinz Avatar answered Oct 18 '22 00:10

Waldheinz