但是,如果我在第一个 for 循环的末尾删除“t = new int[5]”行(即,如果我不“重置”t),那么我的 Cs 数组中的每个对象打印最后分配的 5 个相同的数字。
这是因为通过不创建新数组,您使c 中的所有条目都引用了 same 数组。所以很自然你会看到数组的相同内容。
我建议,由于t 仅对特定循环迭代有用,因此您在循环中声明并创建它。请记住:变量的范围应尽可能窄。所以:
B () {
Random r = new Random();
c = new C[5];
// Don't declare or initialize it here: int[] t; = new int[5];
for (int i=0; i<5; i++) {
int t[] = new int[5]; // *** Keep it specific to the loop, and
// create a new one each iteration
for (int j=0; j<5; j++) {
t[j] = r.nextInt(10) + 1;
}
c[i] = new C(t);
}
for (int k=0; k<5; k++) {
c[k].print();
}
}
为了说明创建和不创建新数组的情况,让我们对内存中的内容进行一些 ASCII 艺术,但使用 3 个元素而不是 5 个元素以使图片更小:
用行每次都创建一个新数组:
Random r = new Random();
c = new int[3];
int[] t = new int[3];
for (int i = 0; i < c.length; ++i) {
for (int j = 0; j < t.length; ++j0 {
t[j] = r.nextInt(10) + 1;
}
c[i] = t;
t = new int[3];
}
就在循环之前,我们在内存中有这个:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ \ +−−−−−−−−−−−+
| 0:空| +−>| (数组) |
| 1:空 | +−−−−−−−−−−−+
| 2:空| | 0:0 |
+−−−−−−−−−−−−−+ | 1:0 |
| 2:0 |
+−−−−−−−−−−−+
注意t 和c 中的那些值,我在此处分别显示为Ref5462 和Ref2634。这些是对象引用。它们是值(就像int 是一个值一样),它们告诉Java 运行时它们所引用的数组在内存中的其他地方。也就是说,数组不是in 变量,数组的位置 是在变量中。 (我们从来没有看到实际值,我在这里使用的数字只是概念性的。)
然后我们运行 j 循环并在 t 中填写值:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ \ +−−−−−−−−−−−+
| 0:空| +−>| (数组) |
| 1:空 | +−−−−−−−−−−−+
| 2:空| | 0:9 |
+−−−−−−−−−−−−−+ | 1:6 |
| 2:5 |
+−−−−−−−−−−−+
然后我们将t的值的副本存储在c[0]中:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ \ +−−−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (数组) |
| 1:空 | +−−−−−−−−−−−+
| 2:空| | 0:9 |
+−−−−−−−−−−−−−+ | 1:6 |
| 2:5 |
+−−−−−−−−−−−+
注意 c[0] 和 t 现在如何包含相同的值。它们都引用同一个数组。 c[0] 和 t 之间没有联系,它们只是具有相同的值。
然后我们创建一个new数组并将新的引用存储在t中:
[t:Ref8465]−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ +−−−−−−−−−−+ |
| 0: Ref5462 |−−−−−->| (数组) | |
| 1:空 | +−−−−−−−−−−+ |
| 2:空| | 0:9 | |
+−−−−−−−−−−−−−+ | 1:6 | |
| 2:5 | |
+−−−−−−−−−−+ | +−−−−−−−−−−−+
+−>| (数组) |
+−−−−−−−−−−−+
| 0:0 |
| 1:0 |
| 2:0 |
+−−−−−−−−−−−+
注意t 中如何有一个新的引用,它指向新的数组。 c[0] 仍然指向旧的。
现在我们再次循环并填写新 t,然后将新的t 的值存储在c[1] 中:
[t:Ref8465]−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ +−−−−−−−−−−+ |
| 0: Ref5462 |−−−−−->| (数组) | |
| 1: Ref8465 |−−−+ +−−−−−−−−−−+ |
| 2:空| | | 0:9 | |
+−−−−−−−−−−−−−+ | | 1:6 | |
| | 2:5 | |
| +−−−−−−−−−−+ \ +−−−−−−−−−−+
+−−−−−−−−−−−−−−−−+−>| (数组) |
+−−−−−−−−−−−+
| 0:2 |
| 1:7 |
| 2:7 |
+−−−−−−−−−−−+
注意c[0] 和c[1] 如何引用不同的 数组。
然后我们再做一遍,创建另一个数组,最后得到这个:
[t:Ref3526]−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ +−−−−−−−−−−+ |
| 0: Ref5462 |−−−−−->| (数组) | |
| 1: Ref8465 |−−−+ +−−−−−−−−−−+ |
| 2: Ref3526 |−+ | | 0:9 | |
+−−−−−−−−−−−−−+ | | | 1:6 | |
| | | 2:5 | |
| | +−−−−−−−−−−+ +−−−−−−−−−−+ |
| +−−−−−−−−−−−−−−−−−−>| (数组) | |
| +−−−−−−−−−−+ |
| | 0:2 | |
| | 1:7 | |
| | 2:7 | |
| +−−−−−−−−−−+ \ +−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| (数组) |
+−−−−−−−−−−−+
| 0:4 |
| 1:5 |
| 2:8 |
+−−−−−−−−−−−+
现在,让我们看看你是否不每次都创建一个新的t:
Random r = new Random();
c = new int[3];
int[] t = new int[3];
for (int i = 0; i < c.length; ++i) {
for (int j = 0; j < t.length; ++j0 {
t[j] = r.nextInt(10) + 1;
}
c[i] = t;
// What if we leave this out? t = new int[3];
}
起初,事情似乎是一样的。在这里,我们再次在第一个循环之后:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ \ +−−−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (数组) |
| 1:空 | +−−−−−−−−−−−+
| 2:空| | 0:9 |
+−−−−−−−−−−−−−+ | 1:6 |
| 2:5 |
+−−−−−−−−−−−+
但此时,我们不创建新数组。所以在第二个循环之后,t 引用的前一个数组中有新值,我们在c[1] 中存储了它的位置副本:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ \ +−−−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (数组) |
| 1: Ref5462 |−−/ +−−−−−−−−−−+
| 2:空| | 0:2 |
+−−−−−−−−−−−−−+ | 1:7 |
| 2:7 |
+−−−−−−−−−−−+
现在,t、c[0] 和 c[1] 都引用 same 数组。在下一个循环之后,我们再次更新了该数组的内容并将c[2] 指向它:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (数组) | |
+−−−−−−−−−−−−−+ \ +−−−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (数组) |
| 1: Ref5462 |−−/ +−−−−−−−−−−+
| 2: Ref5462 |−/ | 0:7 |
+−−−−−−−−−−−−−+ | 1:1 |
| 2:5 |
+−−−−−−−−−−−+
所以很自然,当您输出它时,您会看到重复的相同值。