缘起
今天遇到这么一个问题:
char[] a = new char[2];
for(char i : a){
i = '0';
}
for(char i : a){
System.out.print(i);
}
结果发现,啥都没打印出来 😃
研究一下再上答案
探索
这个foreach循环的原理找不到,于是俺直接找出了编译后的.class
文件:
(备注是俺加上去的)
public class SimpleQuestion {
public SimpleQuestion() {
}
public static void main(String[] args) {
char[] a = new char[2];
//新建一个字符数组
char[] var2 = a;
//数组长度
int var3 = a.length;
int var4;
//这里其实是回归传统的for(;;)循环了
for(var4 = 0; var4 < var3; ++var4) {
//这里创建一个新的字符,但是可以看到循环体里面并没有对原数组的修改
char var10000 = var2[var4];
boolean var5 = true;
}
var2 = a;
var3 = a.length;
for(var4 = 0; var4 < var3; ++var4) {
char i = var2[var4];
System.out.print(i);
}
}
}
前面这个是一般的变量,现在看一下假如数组里面是对象会咋样:
public class SimpleQuestion {
public static void main(String[] args) {
Apple a1 = new Apple(1,1);
Apple a2 = new Apple(2,2);
Apple[] a = {a1, a2};
for(Apple apple : a){
apple = new Apple(3,3);
}
for(Apple i : a){
System.out.println(i.toString());
}
}
}
class Apple{
int color;
int number;
Apple(int color, int number){
this.color = color;
this.number = number;
};
public String toString(){
StringBuilder s = new StringBuilder();
s.append("color:").append(color).append(" ").append("number:").append(number);
return s.toString();
}
}
运行结果:
显然,对象也没有被改变;
去看编译好的.class
文件:
public static void main(String[] args) {
Apple a1 = new Apple(1, 1);
Apple a2 = new Apple(2, 2);
Apple[] a = new Apple[]{a1, a2};
Apple[] var4 = a;
int var5 = a.length;
int var6;
for(var6 = 0; var6 < var5; ++var6) {
Apple var10000 = var4[var6];
//这里虽然new了一个新的对象,但是并没有进行赋值或者其他操作
new Apple(3, 3);
}
var4 = a;
var5 = a.length;
for(var6 = 0; var6 < var5; ++var6) {
Apple i = var4[var6];
System.out.println(i.toString());
}
}
现在看能否改变对象(而不是替换):
修改前面代码段:
public static void main(String[] args) {
Apple a1 = new Apple(1,1);
Apple a2 = new Apple(2,2);
Apple[] a = {a1, a2};
for(Apple apple : a){
//这里对对象的属性进行修改
apple.number = 3;
}
for(Apple i : a){
System.out.println(i.toString());
}
}
运行结果:
修改成功了,再去看下.class
:
public static void main(String[] args) {
Apple a1 = new Apple(1, 1);
Apple a2 = new Apple(2, 2);
Apple[] a = new Apple[]{a1, a2};
Apple[] var4 = a;
int var5 = a.length;
int var6;
Apple i;
for(var6 = 0; var6 < var5; ++var6) {
//这里i成为对象的引用
i = var4[var6];
//对属性进行了修改
i.number = 3;
}
var4 = a;
var5 = a.length;
for(var6 = 0; var6 < var5; ++var6) {
i = var4[var6];
System.out.println(i.toString());
}
}
总结
foreach循环不能修改对象/变量的值,但是可以修改对象的内部属性。