Avatar ·

Como realmente funciona o loop for-each em Java? Explicação detalhada com exemplos

Olá a todos! Comecei a estudar Java recentemente e me deparei com o loop for-each. Parece tudo claro: for (int x : numbers) { ... } — simplesmente itera sobre os elementos de um array ou collection. Mas quando comecei a me aprofundar, surgiram muitas perguntas. Por exemplo, escrevi este código:
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");

for (String s : list) {
    if (s.equals("B")) {
        list.remove(s); // ConcurrentModificationException!
    }
}
E recebi ConcurrentModificationException. Por quê? No for normal (for (int i = 0; i < list.size(); i++)) isso não acontece. Outro exemplo — tentei modificar os elementos de um array usando for-each:
int[] arr = {1, 2, 3};
for (int x : arr) {
    x = x * 2; // Não funciona! O array não mudou
}
Por que x não referencia o elemento do array? E o que realmente acontece "por baixo dos panos"? O for-each pode trabalhar com qualquer tipo de dado? Como o compilador