Nếu tôi gọi clone()
phương thức trên mảng Đối tượng kiểu A, nó sẽ sao chép các phần tử của nó như thế nào? Bản sao có tham chiếu đến các đối tượng giống nhau không? Hay nó sẽ gọi (element of type A).clone()
cho từng người trong số họ?
Nếu tôi gọi clone()
phương thức trên mảng Đối tượng kiểu A, nó sẽ sao chép các phần tử của nó như thế nào? Bản sao có tham chiếu đến các đối tượng giống nhau không? Hay nó sẽ gọi (element of type A).clone()
cho từng người trong số họ?
Câu trả lời:
clone()
tạo ra một bản sao nông. Có nghĩa là các phần tử sẽ không được nhân bản. (Điều gì sẽ xảy ra nếu họ không triển khai Cloneable
?)
Bạn có thể muốn sử dụng Arrays.copyOf(..)
để sao chép mảng thay vì clone()
(mặc dù sao chép là tốt cho mảng, không giống như bất kỳ thứ gì khác)
Nếu bạn muốn nhân bản sâu, hãy kiểm tra câu trả lời này
Một ví dụ nhỏ để minh họa mức độ nông cạn của clone()
ngay cả khi các phần tử là Cloneable
:
ArrayList[] array = new ArrayList[] {new ArrayList(), new ArrayList()};
ArrayList[] clone = array.clone();
for (int i = 0; i < clone.length; i ++) {
System.out.println(System.identityHashCode(array[i]));
System.out.println(System.identityHashCode(clone[i]));
System.out.println(System.identityHashCode(array[i].clone()));
System.out.println("-----");
}
Bản in:
4384790
4384790
9634993
-----
1641745
1641745
11077203
-----
System.arrayCopy
clone()
là một lựa chọn tốt để sử dụng với các mảng..chất riêng. Bloch đề cập rằng anh ấy sẽ chỉ sử dụng nó cho các mảng và không có gì khác. System.arrayCopy
Ổn. Arrays.copyOf(..)
là một giải pháp thay thế khác dễ sử dụng hơn.
Arrays.copyOf
:-) Nó có một chữ ký phương thức giúp đơn giản hóa các biến (vâng, nó hạn chế bạn, nhưng nó hoàn hảo cho hầu hết các trường hợp) và ít nhất trong JDK của tôi, nó được triển khai bằng cách sử dụng System.arrayCopy
. Cảm ơn vì mẹo đó!
array[i].clone()
KHÔNG đề cập đến array[i]
. Đó là những gì mà một phần của ví dụ đang chứng minh.
Nếu tôi gọi phương thức clone () trên mảng Đối tượng kiểu A, nó sẽ sao chép các phần tử của nó như thế nào?
Các phần tử của mảng sẽ không được sao chép.
Bản sao có tham chiếu đến các đối tượng giống nhau không?
Đúng.
Hay nó sẽ gọi (phần tử của loại A) .clone () cho mỗi người trong số họ?
Không, nó sẽ không gọi clone()
bất kỳ phần tử nào.
Mảng nguyên thủy 1D thực hiện sao chép các phần tử khi nó được nhân bản. Điều này thôi thúc chúng ta sao chép mảng 2D (Array of Arrays).
Hãy nhớ rằng bản sao mảng 2D không hoạt động do triển khai bản sao nông của clone()
.
public static void main(String[] args) {
int row1[] = {0,1,2,3};
int row2[] = row1.clone();
row2[0] = 10;
System.out.println(row1[0] == row2[0]); // prints false
int table1[][]={{0,1,2,3},{11,12,13,14}};
int table2[][] = table1.clone();
table2[0][0] = 100;
System.out.println(table1[0][0] == table2[0][0]); //prints true
}
clone
1D mảng nguyên thủy và nhận bản sao sâu? Điều đó rất tuyệt vời! Giá vé tốt Arrays.copyOfRange()
, System.arraycopy()
!
Bản sao là một bản sao nông của mảng.
Mã kiểm tra này in ra:
[1, 2] / [1, 2] [100, 200] / [100, 2]
bởi vì MutableInteger
được chia sẻ trong cả hai mảng như objects[0]
và objects2[0]
, nhưng bạn có thể thay đổi tham chiếu objects[1]
một cách độc lập với objects2[1]
.
import java.util.Arrays;
public class CloneTest {
static class MutableInteger {
int value;
MutableInteger(int value) {
this.value = value;
}
@Override
public String toString() {
return Integer.toString(value);
}
}
public static void main(String[] args) {
MutableInteger[] objects = new MutableInteger[] {
new MutableInteger(1), new MutableInteger(2) };
MutableInteger[] objects2 = objects.clone();
System.out.println(Arrays.toString(objects) + " / " +
Arrays.toString(objects2));
objects[0].value = 100;
objects[1] = new MutableInteger(200);
System.out.println(Arrays.toString(objects) + " / " +
Arrays.toString(objects2));
}
}