The difference between both codes can be seen in their generated bytecodes.
The first one has extra two instructions over the second one; it stores the return value of someMethod()
on the local stack and then loads it again for accessing it's iterator.
However the second one immediately uses the Iterator
without storing the return value of someMethod()
on the local stack.
Below code shows the elimination of 3:
and 4:
instructions.
First:
Collection<String> collection = someMethod();
for(String element : collection) { ... }
0: invokestatic #3 // Call someMethod()
3: astore_1 // Store the result as first item on local stack
4: aload_1 // Load the Collection again into operand stack
5: invokeinterface #4, 1 // Get Iterator (of Collection) - InterfaceMethod java/util/Collection.iterator:()Ljava/util/Iterator;
10: astore_2 // Store Iterator on local stack #2
11: aload_2 // LOOP STARTS - Load iterator
12: invokeinterface #5, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
17: ifeq 33
20: aload_2
21: invokeinterface #6, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
26: checkcast #7 // class java/lang/String
29: astore_3
30: goto 11 // LOOP ENDS
33: return
Second
for(String element : someMethod()) { ... }
0: invokestatic #3 // Call someMethod()
3: invokeinterface #4, 1 // Get Iterator (of Collection) - Interface Method java/util/Collection.iterator:()Ljava/util/Iterator;/
8: astore_1 // Store Iterator on local stack #2
9: aload_1 // LOOP STARTS - Load iterator
10: invokeinterface #5, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
15: ifeq 31
18: aload_1
19: invokeinterface #6, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
24: checkcast #7 // class java/lang/String
27: astore_2
28: goto 9 // LOOP ENDS
31: return
BTW, I don't think that they will have a big difference in terms of performance since both have 9 instructions inside the loop.