List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
for(String s: list)
s = s+"1";
println(list);
输出:
[1, 2, 3]
看起来 s 好像确实不可写。
再看另外一个例子:
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);
输出:
[0, 0, 0]
为什么这个却可以改?
再往下:
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 时注意避免第一种写法。另外,我认为编译器是可以发现并给予警告的:
for(String s: list){
s = s+"1";
// 如果后面没有再用到 s 的代码,编译器完全可以对
// 上述情况进行警告的;如果严格一点,就算后面还有引用
// s 的代码也可以警告一下的。
}
最后给出别人给我的提示来源:http://www.imooc.com/article/11197