List<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("3"); for(String s: list) s = s+"1"; println(list);
輸出:java
[1, 2, 3]數組
看起來 s 好像確實不可寫。ide
再看另一個例子:this
class A{ private int i; A(int i){ this.i = i; } void set(int i){ this.i = i; } @Override public String toString() { return ""+i; } } List<A> aList = new ArrayList<A>(); aList.add(new A(1)); aList.add(new A(2)); aList.add(new A(3)); for(A a: aList) a.set(0); println(aList);
輸出:code
[0, 0, 0]編譯器
爲何這個卻能夠改?編譯
再往下:class
int a = 1;//等價於給數組賦值 int b = a;//b指向數組a 也就至關於b是元素變量 b = 2;//更改元素變量 System.out.println(a);//a的值依然是1,只是b變了而已
如今明白了吧:變量
for(String s: list) s = s+"1";
裏的 s 只是一個臨時引用,它指向 list 中的一個元素,但若你強制讓它指向另一個元素,原來 list 中的元素也不會所以而改變的。但 class A 則有點不同,它操做的則是原始數據,因此是能夠修改 list 中的元素的。foreach
所以寫 foreach 時注意避免第一種寫法。另外,我認爲編譯器是能夠發現並給予警告的:
for(String s: list){ s = s+"1"; // 若是後面沒有再用到 s 的代碼,編譯器徹底能夠對 // 上述狀況進行警告的;若是嚴格一點,就算後面還有引用 // s 的代碼也能夠警告一下的。 }
最後給出別人給個人提示來源:http://www.imooc.com/article/11197