'nông' hay 'sâu' - và đây là một vấn đề mà tôi thấy không có một định nghĩa chính xác - phương pháp Arrays.copyOf(..)
DOES trong thực tế sản xuất một bản sao của mảng nguồn không bị ảnh hưởng bởi các thay đổi đối với mảng nguồn.
Lấy ví dụ đơn giản sau đây với int mảng:
import java.util.Arrays;
public class DeepCopyTest
{
public static void main(String[] args)
{
int[] source = { 1, 2, 3, 4, 5, 6};
int[] target = new int[source.length];
// Copy target from source via Arrays.copyOf(..) method :
target = Arrays.copyOf(source, 6);
// Check for equality :
System.out.println("Source1 : " + Arrays.toString(source));
System.out.println("Target1 : " + Arrays.toString(target));
// Increment all entries in source array :
for(int i = 0; i < source.length; i++)
{
source[i] = source[i] +1;
}
// See if target is affected :
System.out.println("Source2 : " + Arrays.toString(source));
System.out.println("Target2 : " + Arrays.toString(target));
}
}
// OUTPUT
// ------
Source1 : [1, 2, 3, 4, 5, 6]
Target1 : [1, 2, 3, 4, 5, 6]
Source2 : [2, 3, 4, 5, 6, 7]
Target2 : [1, 2, 3, 4, 5, 6]
Trong thực tế, khi mọi người tìm kiếm một "bản sao sâu" của một mảng, họ chỉ muốn một cái gì đó mà không bị ảnh hưởng bởi những thay đổi với bản gốc.
Và phương thức Arrays.copyOf (..) `này cung cấp cho chúng điều này.
Cũng như mảng kiểu nguyên thủy, mảng đối tượng String cũng cư xử như ví dụ trên, cho sản lượng như:
Source1 : [a, b, c, d, e, f]
Target1 : [a, b, c, d, e, f]
Source2 : [a1, b1, c1, d1, e1, f1]
Target2 : [a, b, c, d, e, f]
khi các mục mảng nguồn ban đầu được nối bằng "1".
Nó cũng 'hoạt động' cho mảng Đối tượng theo nghĩa là mục tiêu không còn gắn với nguồn khi mục tiêu được gán lại. NHƯNG nhìn vào đầu ra cho các yếu tố đầu tiên của cả hai mảng sau khi sao chép và sau đó sau khi thay đổi nguồn [0] tiết lộ sự thật đầy đủ:
Source1 : [email protected]
Target1 : [email protected]
Source2 : [email protected]
Target2 : [email protected]
Sau khi mảng nguồn gốc được sao chép, các yếu tố mục tiêu chỉ đơn giản là đã được chỉ với bất kỳ giá trị nào hiện đang được giữ trong các đối tác nguồn của chúng. Đối với mục tiêu [0] nó là nội dung của địa chỉ bộ nhớ 1db9742 - cũng là cùng một địa chỉ bộ nhớ giữ nguồn [0]. . . .
Và lý do chúng tôi có được một debonding giữa nguồn và đích sau khi nguồn [0] được bố trí là do thực tế rằng tuyên bố nhiệm vụ
source[0] = new Object();
chỉ đơn giản là làm cho tài liệu tham khảo bộ nhớ được tổ chức tại nguồn [0] để được thay đổi thành một số vị trí mới như một đối tượng mới đang được chỉ ra. Vì vậy, nó không phải là sau khi tất cả một bản sao sâu thật sự trong ý nghĩa tinh khiết, mặc dù trong nhiều trường hợp nó mang lại cho coder những lợi ích tương tự như một bản sao sâu.
Với mảng dữ liệu nguyên thủy, phương thức Arrays.copyOf (..) không thể sao chép tham chiếu vì chúng không được sử dụng cho nguyên thủy. Nó chỉ sao chép các giá trị phần tử nguồn vào các phần tử đích. Một lần nữa chúng ta có tác dụng tương tự như một bản sao sâu tại các chi phí của một hoạt động cần mã ít hơn nhiều so với một bản sao sâu.
Vì vậy, Arrays.copyOf (..) là bản sao sâu 'rẻ' cho cả mảng nguyên thủy và đối tượng 1-D. Nhưng bất kỳ mảng dữ liệu phức tạp hơn và nó được phát hiện ra.
Có thể nó nên được gọi là bản sao bán sâu.
Có lẽ chỉ là một sự xuất hiện khác của việc thực hiện chuỗi – Matthias
@Matthias: Tôi không nghĩ vậy. Vì "Foo" là một chữ, nó sẽ được thực tập; các thử nghiệm giả định rằng. Nếu giả định đó là chính xác, thì các thử nghiệm đang điều tra xem phần tử đích có bị thay đổi bởi '=" Bar "' của phần tử nguồn tương ứng hay không. – ToolmakerSteve
Tôi không thấy nơi các bài kiểm tra đưa ra bất kỳ giả định nào về việc liệu Chuỗi có được nội bộ hóa hay không.Tôi không thấy bất kỳ bài kiểm tra nhận dạng nào, tôi chỉ thấy các bài kiểm tra bình đẳng. Các kết quả sẽ giống hệt nhau đối với các bản sao nông và sâu, vì các xét nghiệm bình đẳng không thể khác nhau giữa các bản sao nông và sâu. Một trong những nhu cầu kiểm tra nhận dạng để khác nhau giữa các bản sao nông và sâu. –