But if I remove the line "t = new int[5]" at the end of the first for-loop (ie., if I don't "reset" t), then every object in my array of Cs prints the same 5 numbers that were the last to be assigned.
That's because by not creating a new array, you're making all of the entries in c
refer to the same array. So naturally you see the same contents of the array.
I'd suggest that since t
is only useful in regard to a specific loop iteration, you declare and create it in the loop. Remember: Variables should be scoped as narrowly as possible. So:
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();
}
}
To illustrate what's going on both with and without creating a new array, let's do some ASCII-art for what's in memory as we go, but with 3 elements rather than 5 to keep the pictures smaller:
With the line creating a new array each time:
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];
}
Right before the loop, we have this in memory:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ \ +−−−−−−−−−+
| 0: null | +−>| (array) |
| 1: null | +−−−−−−−−−+
| 2: null | | 0: 0 |
+−−−−−−−−−−−−+ | 1: 0 |
| 2: 0 |
+−−−−−−−−−+
Note those values in t
and c
, which I've shown there as Ref5462
and Ref2634
respectively. Those are object references. They're values (just like an int
is a value), and they tell the Java runtime where the array they refer to is, elsewhere in memory. That is, the array isn't in the variable, the location of the array is in the variable. (We never see the actual values, the numbers I'm using here are just conceptual.)
Then we run our j
loop and fill in values in t
:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ \ +−−−−−−−−−+
| 0: null | +−>| (array) |
| 1: null | +−−−−−−−−−+
| 2: null | | 0: 9 |
+−−−−−−−−−−−−+ | 1: 6 |
| 2: 5 |
+−−−−−−−−−+
Then we store a copy of the value of t
in c[0]
:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ \ +−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (array) |
| 1: null | +−−−−−−−−−+
| 2: null | | 0: 9 |
+−−−−−−−−−−−−+ | 1: 6 |
| 2: 5 |
+−−−−−−−−−+
Note how c[0]
and t
contain the same value now. They both refer to the same array. There is no link between c[0]
and t
, they just have the same value in them.
Then we create a new array and store the new reference to it in t
:
[t:Ref8465]−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ +−−−−−−−−−+ |
| 0: Ref5462 |−−−−−>| (array) | |
| 1: null | +−−−−−−−−−+ |
| 2: null | | 0: 9 | |
+−−−−−−−−−−−−+ | 1: 6 | |
| 2: 5 | |
+−−−−−−−−−+ | +−−−−−−−−−+
+−>| (array) |
+−−−−−−−−−+
| 0: 0 |
| 1: 0 |
| 2: 0 |
+−−−−−−−−−+
Note how t
has a new reference in it, which points to the new array. c[0]
still points to the old one.
Now we loop again and fill in the new t
, then store that new t
's value in c[1]
:
[t:Ref8465]−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ +−−−−−−−−−+ |
| 0: Ref5462 |−−−−−>| (array) | |
| 1: Ref8465 |−−−+ +−−−−−−−−−+ |
| 2: null | | | 0: 9 | |
+−−−−−−−−−−−−+ | | 1: 6 | |
| | 2: 5 | |
| +−−−−−−−−−+ \ +−−−−−−−−−+
+−−−−−−−−−−−−−−−+−>| (array) |
+−−−−−−−−−+
| 0: 2 |
| 1: 7 |
| 2: 7 |
+−−−−−−−−−+
Note how c[0]
and c[1]
refer to different arrays.
Then we do it all again, creating another array, and end up with this:
[t:Ref3526]−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ +−−−−−−−−−+ |
| 0: Ref5462 |−−−−−>| (array) | |
| 1: Ref8465 |−−−+ +−−−−−−−−−+ |
| 2: Ref3526 |−+ | | 0: 9 | |
+−−−−−−−−−−−−+ | | | 1: 6 | |
| | | 2: 5 | |
| | +−−−−−−−−−+ +−−−−−−−−−+ |
| +−−−−−−−−−−−−−−−−>| (array) | |
| +−−−−−−−−−+ |
| | 0: 2 | |
| | 1: 7 | |
| | 2: 7 | |
| +−−−−−−−−−+ \ +−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−>| (array) |
+−−−−−−−−−+
| 0: 4 |
| 1: 5 |
| 2: 8 |
+−−−−−−−−−+
Now, let's look at it if you don't create a new t
each time:
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];
}
At first, things seem the same. Here we are after the first loop again:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ \ +−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (array) |
| 1: null | +−−−−−−−−−+
| 2: null | | 0: 9 |
+−−−−−−−−−−−−+ | 1: 6 |
| 2: 5 |
+−−−−−−−−−+
But at this point, we don't create a new array. So after the second loop, the previous array that t
refers to has new values in it, and we've stored a copy of its location in c[1]
:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ \ +−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (array) |
| 1: Ref5462 |−−/ +−−−−−−−−−+
| 2: null | | 0: 2 |
+−−−−−−−−−−−−+ | 1: 7 |
| 2: 7 |
+−−−−−−−−−+
Now, t
, c[0]
, and c[1]
all refer to the same array. After the next loop, we've updated the contents of that array again and pointed c[2]
at it:
[t:Ref5462]−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−+ |
[c:Ref2534]−−>| (array) | |
+−−−−−−−−−−−−+ \ +−−−−−−−−−+
| 0: Ref5462 |−−−+−>| (array) |
| 1: Ref5462 |−−/ +−−−−−−−−−+
| 2: Ref5462 |−/ | 0: 7 |
+−−−−−−−−−−−−+ | 1: 1 |
| 2: 5 |
+−−−−−−−−−+
So naturally, when you output it, you see the same values repeated.