foreachとにかくフードの下でイテレータを使用します。それは実際には単なる構文上の砂糖です。
次のプログラムを検討してください。
import java.util.List;
import java.util.ArrayList;
public class Whatever {
    private final List<Integer> list = new ArrayList<>();
    public void main() {
        for(Integer i : list) {
        }
    }
}
レッツは、とそれをコンパイルしjavac Whatever.java、
そして逆アセンブルのバイトコードを読んでmain()、使用しましたjavap -c Whatever:
public void main();
  Code:
     0: aload_0
     1: getfield      #4                  // Field list:Ljava/util/List;
     4: invokeinterface #5,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
     9: astore_1
    10: aload_1
    11: invokeinterface #6,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
    16: ifeq          32
    19: aload_1
    20: invokeinterface #7,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    25: checkcast     #8                  // class java/lang/Integer
    28: astore_2
    29: goto          10
    32: return
以下のforeachようなプログラムにコンパイルされることがわかります。
- を使用してイテレータを作成します 
List.iterator() 
- If 
Iterator.hasNext():Iterator.next()ループを呼び出して続行します 
「この役に立たないループがコンパイルされたコードから最適化されないのはなぜですか?リスト項目では何も実行されないことがわかります」:.iterator()副作用のある反復可能コードをコーディングすることは可能です、またはそのため、.hasNext()副作用または意味のある結果をもたらします。
データベースからのスクロール可能なクエリを表すイテラブルが劇的な何かをする.hasNext()(データベースに接続する、または結果セットの最後に到達したためにカーソルを閉じるなど)と簡単に想像できます。
したがって、ループ本体で何も起こらないことを証明できたとしても、反復しても意味のある/結果が何も起こらないことを証明する方がコストがかかります(扱いにくい?)。コンパイラーはこの空のループ本体をプログラムに残さなければなりません。
私たちが期待できる最高のものは、コンパイラの警告です。この空のループ本体について警告javac -Xlint:all Whatever.javaしないのは興味深いことです。IntelliJ IDEAはそうします。確かに、Eclipseコンパイラを使用するようにIntelliJを設定しましたが、それが理由ではないかもしれません。
