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

Usually for each cycle the usual form is used:

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

But if I want to save the bar until the loop, I cannot use 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 received the syntax error mentioned above.

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

Unlike a regular loop, a variable can be declared outside or not at all ...

 int i = 1; for(;i<max;i++){ for(;;){ // Do things } } 
+46
java syntax foreach
May 26 '11 at 9:42 a.m.
source share
4 answers

This is a good question, and I would be glad to see some kind of detailed answer. However, the official documentation reads:

These flaws were known to designers who decided to go with a clean, simple design, which in most cases.

The vast majority of cases are the answer for me.

On the side of the note, personally, I think the foreach in Java is just good syntax for a standard iterator loop. Thus, the compiler creates an iterator for the structure and uses the variable to get the value for the current iteration. To make sure the variable has been initialized, you need to declare it for the loop area (and I think this prevents the variable from being used in another place, for example, in a different thread). Because of this, you cannot use a variable after a loop. But, this is just my opinion, and I would be very glad to hear from someone who knows this better. :)

Edit Here's an interesting article on foreach loops in Java.

Other editing I analyzed (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 last method uses invokevirtual #8 . However, both calls result in a call to the same Iterator method. Thus, it seems that foreach is nothing more than syntactic sugar, which the compiler simply translates into a predefined construct, just like the documentation says. This does not answer the question of why this is so. I, although it is simply interesting and perhaps worth knowing in the context of the discussion.

+28
May 26 '11 at 9:59 a.m.
source share

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

These flaws were known to designers who made the conscious decision to go with a clean, simple design that would cover the vast majority of cases.

As we know, the behavior you are asking for can be modeled by simply extending the for-each loop to an old style based on an iterator, and maybe they just thought it was good enough.

+4
May 26 '11 at 9:57 a.m.
source share

In this case, the list enumeration method:

 Foo bar = null; for(Iterator<Foo> barIterator = bars.iterator(); barIterator.hasNext();){ bar = barIterator.next(); // or whatever else you want to do ... } 

Do not iterate over a list using an index, unless that list implements RandomAccess!

The extended for loop is just syntactic sugar for this iterator approach, which stores the variable (here bar) locally in the loop. (Generally, keeping variables as local as possible is good.)

+3
May 26 '11 at 9:56 a.m.
source share

The purpose of this new syntax is beautification, as it actually does not add anything new in Java. I assume that they did not allow the syntax that you did for the sole reason: This is not beautiful! :)

+1
May 26 '11 at 9:59 a.m.
source share



All Articles