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