System.arraycopy() và Arrays.copyOf() thực hiện sao chép nông hay sâu trong Java

Khi làm việc với mảng trong Java, hai phương thức System.arraycopy()Arrays.copyOf() thường được sử dụng để sao chép dữ liệu. Tuy nhiên, hành vi sao chép của chúng phụ thuộc vào kiểu dữ liệu của phần tử trong mảng.

Trường hợp kiểu dữ liệu nguyên thủy

Integer[] origin = {12, 23, 45};
Integer[] copiedViaArrays = Arrays.copyOf(origin, 3);
Integer[] copiedViaSystem = new Integer[3];
System.arraycopy(origin, 0, copiedViaSystem, 0, 3);

System.out.println("Trước khi thay đổi:");
System.out.println("Gốc[0]: " + origin[0]);
System.out.println("Arrays.copy[0]: " + copiedViaArrays[0]);
System.out.println("System.copy[0]: " + copiedViaSystem[0]);

origin[0] = 121;

System.out.println("Sau khi thay đổi:");
System.out.println("Gốc[0]: " + origin[0]);
System.out.println("Arrays.copy[0]: " + copiedViaArrays[0]);
System.out.println("System.copy[0]: " + copiedViaSystem[0]);

Kết quả cho thấy giá trị trong các mảng sao chép không bị ảnh hưởng — đây là sao chép sâu đối với giá trị nguyên thủy.

Trường hợp kiểu String

String[] source = {"alpha", "beta", "gamma"};
String[] viaArrays = Arrays.copyOf(source, 3);
String[] viaSystem = new String[3];
System.arraycopy(source, 0, viaSystem, 0, 3);

source[0] = "omega";

// Các mảng sao chép vẫn giữ giá trị ban đầu

Vì String là immutable, việc gán lại tham chiếu không ảnh hưởng đến bản sao — kết quả tương tự như sao chép sâu.

Trường hợp đối tượng tùy chỉnh

class Person {
    private String fullName;
    private int yearsOld;

    public Person(String name, int age) {
        this.fullName = name;
        this.yearsOld = age;
    }

    public void updateInfo(String name, int age) {
        this.fullName = name;
        this.yearsOld = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + fullName + "', age=" + yearsOld + "}";
    }
}

Person[] originals = {
    new Person("Lê Văn A", 25),
    new Person("Nguyễn Thị B", 30)
};

Person[] duplicate1 = Arrays.copyOf(originals, 2);
Person[] duplicate2 = new Person[2];
System.arraycopy(originals, 0, duplicate2, 0, 2);

originals[0].updateInfo("Lê Văn A (mới)", 26);

// Tất cả đều hiển thị thông tin mới — sao chép nông

Khi thay đổi trạng thái đối tượng, tất cả các bản sao đều phản ánh sự thay đổi — chứng tỏ chỉ sao chép tham chiếu, không sao chép đối tượng bên trong.

Kết luận

Cả System.arraycopy()Arrays.copyOf() đều tạo ra mảng mới — tức là sao chép sâu ở cấp độ mảng. Tuy nhiên, với phần tử bên trong:

  • Nếu là kiểu nguyên thủy, String, hoặc wrapper class → sao chép sâu (do giá trị hoặc tính bất biến).
  • Nếu là đối tượng tùy chỉnh → sao chép nông (chỉ sao chép tham chiếu).

Thẻ: Java System.arraycopy Arrays.copyOf shallow-copy deep-copy

Đăng vào ngày 27 tháng 6 lúc 23:33