考虑:

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
    System.out.println(item);
}

如果不使用for each语法,等价的for循环会是什么样子?


当前回答

正如许多其他答案正确指出的那样,for each循环只是同一个旧for循环的语法糖,编译器将其转换为同一个老for循环。

javac(OpenJDK)有一个开关-XD printflat,它生成一个Java文件,去掉了所有语法糖。完整的命令如下所示:

javac -XD-printflat -d src/ MyFile.java

//-d is used to specify the directory for output java file

所以让我们去掉语法糖

为了回答这个问题,我创建了一个文件,并为每个文件编写了两个版本,一个带有数组,另一个带有列表。我的Java文件如下所示:

import java.util.*;

public class Temp{

    private static void forEachArray(){
        int[] arr = new int[]{1,2,3,4,5};
        for(int i: arr){
            System.out.print(i);
        }
    }

    private static void forEachList(){
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        for(Integer i: list){
            System.out.print(i);
        }
    }
}

当我用上面的开关编译这个文件时,我得到了以下输出。

import java.util.*;

public class Temp {

    public Temp() {
        super();
    }

    private static void forEachArray() {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        for (/*synthetic*/ int[] arr$ = arr, len$ = arr$.length, i$ = 0; i$ < len$; ++i$) {
            int i = arr$[i$];
            {
                System.out.print(i);
            }
        }
    }

    private static void forEachList() {
        List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5)});
        for (/*synthetic*/ Iterator i$ = list.iterator(); i$.hasNext(); ) {
            Integer i = (Integer)i$.next();
            {
                System.out.print(i);
            }
        }
    }
}

您可以看到,与其他语法糖(Autoboxing)一起,每个循环都被更改为简单循环。

其他回答

这是一个等价的表达式。

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}

它看起来像这样。非常粗糙。

for (Iterator<String> i = someList.iterator(); i.hasNext(); )
        System.out.println(i.next());

Sun文档中对每一项都有很好的描述。

for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
   String item = itr.next();
   System.out.println(item);
}

每个的构造也对数组有效。例如

String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };

for (String fruit : fruits) {
    // fruit is an element of the `fruits` array.
}

这基本上等同于

for (int i = 0; i < fruits.length; i++) {
    String fruit = fruits[i];
    // fruit is an element of the `fruits` array.
}

因此,总体总结如下:[nsayer]以下是正在发生的事情的较长形式:

for(Iterator<String>i=someList.iiterator();i.hasNext();){字符串项=i.next();System.out.println(项);}注意,如果您需要使用i.移除();或访问实际的迭代器不能使用for(:)习惯用法,因为实际的迭代器只是推断。

[丹尼斯·布埃诺]

nsayer的回答暗示了这一点,但是值得注意的是,OP用于(..)当“someList”为任何实现的东西java.lang.Iterable--它没有成为列表,或来自甚至你自己的类型,因此,可以与此一起使用语法。

正如许多其他答案正确指出的那样,for each循环只是同一个旧for循环的语法糖,编译器将其转换为同一个老for循环。

javac(OpenJDK)有一个开关-XD printflat,它生成一个Java文件,去掉了所有语法糖。完整的命令如下所示:

javac -XD-printflat -d src/ MyFile.java

//-d is used to specify the directory for output java file

所以让我们去掉语法糖

为了回答这个问题,我创建了一个文件,并为每个文件编写了两个版本,一个带有数组,另一个带有列表。我的Java文件如下所示:

import java.util.*;

public class Temp{

    private static void forEachArray(){
        int[] arr = new int[]{1,2,3,4,5};
        for(int i: arr){
            System.out.print(i);
        }
    }

    private static void forEachList(){
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        for(Integer i: list){
            System.out.print(i);
        }
    }
}

当我用上面的开关编译这个文件时,我得到了以下输出。

import java.util.*;

public class Temp {

    public Temp() {
        super();
    }

    private static void forEachArray() {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        for (/*synthetic*/ int[] arr$ = arr, len$ = arr$.length, i$ = 0; i$ < len$; ++i$) {
            int i = arr$[i$];
            {
                System.out.print(i);
            }
        }
    }

    private static void forEachList() {
        List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5)});
        for (/*synthetic*/ Iterator i$ = list.iterator(); i$.hasNext(); ) {
            Integer i = (Integer)i$.next();
            {
                System.out.print(i);
            }
        }
    }
}

您可以看到,与其他语法糖(Autoboxing)一起,每个循环都被更改为简单循环。