来自不同的语言,这似乎让我感到困惑。
String [] names = new String[]{"A","B","C"};
for (String n : names){
n = new String(n+"hello");
}
System.out.println(Arrays.toString(names)); // [A, B, C]
names
仍然具有原始值 [A,B,C],我相信这是由于不变性,但这是否意味着我在遍历数组时创建了三个可回收的垃圾字符串?
但是这段代码确实修改了数组?
Car [] cars = { new Car("red"), new Car("green") };
for(int i=0; i<cars.length; i++){
Car c = cars[i];
c.color ="black";
}
for(int i=0; i<cars.length; i++){
Car c = cars[i];
System.out.println(c.color); //prints black, black
}
最佳答案
这段代码
for (String n : names){
n = new String(n+"hello");
}
与
相同for (int i = 0; i<names.length; i++){
String n = names[i];
n = new String(n+"hello");
}
所以正如你所看到的分配n
新值不能影响数组。是的,在每次迭代结束时通过 new String(n+"hello");
创建的字符串将有资格进行垃圾收集。
但是自n
默认情况下拥有与 names[i]
相同的对象您可以使用它来更改持有对象的状态。例如,如果您的数组是 Persons
的数组, 通过 n
您将能够更改属性,例如 age
存储的人
n.setAge(42);
您还可以为 n
分配新值,
n = new Person("Jack", 40);
但这并不意味着您要为 names[i]
分配新值因为n
和 names[i]
是不同的变量。
也许这对你有一点帮助
当n = names[i]
情况是这样的:
names[i] ----+ +--------+
| | Person |
+------>+--------+
| | name | //Adam
n ----+ | age | //30
+--------+
因此两个变量(引用)都持有相同的实例,这允许您从两个变量对其进行操作(如果您通过 name
更改 age
或 n
,您也将通过 names[i]
看到此更改。因为他们持有相同的对象)
但如果你这样做
n = new Person("Jack", 42);
您仅将新对象分配给 n
,而不是names[i]
, 所以情况会是
+--------+
| Person |
names[i] ----------->+--------+
| name | //Adam
| age | //30
+--------+
+--------+
| Person |
n ----------->+--------+
| name | //Jack
| age | //42
+--------+
这意味着数组 ( names[i]
) 没有改变。
简而言之 n
你不能放 new
元素到数组,但您可以更改现有元素的状态。
关于java - 在符合 GC 条件的 Java For Each 循环中创建的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28184097/