Copy Constructor trong Java

Copy constructor trong Java là một constructor dùng để khởi tạo một object trong đó sử dụng một object khác có cùng kiểu dữ liệu.

Copy constructor sẽ hữu ích khi chúng ta muốn sao chép dữ liệu từ một object (các giá trị của các trường bên trong object) khác sang một object mới.

Cách triển khai copy constructor

Để triển khai một copy constructor thì chúng ta cần tạo một constructor với tham số đầu vào là một object có cùng kiểu dữ liệu. Sau đó tiến hành khởi tạo giá trị của từng thuộc tính bên trong tương ứng với giá trị của object được truyền vào.

public class Employee {
    private int id;
    private String name;
    
    public Employee(Employee employee) {
        this.id = employee.id;
        this.name = employee.name;
    }
}

Ở đoạn code trên chúng ta đã có một hàm copy giúp tạo ra một object mới được sao chép từ một object đã tồn tại trước đó hay còn gọi là shallow copy. Shallow copy hoạt động tốt khi các thuộc tính trong class có kiểu dữ liệu int, long , String hay tóm lại là các kiểu dữ liệu nguyên thủy và các immutable type.

Nếu trong một class có một hoặc nhiều thuộc tính có kiểu dữ liệu là mutable thì chúng ta cần triển khai deep copy để object được tạo mới hoàn toàn độc lập với object được sao chép.

Ví dụ trong Employee chứa thuộc tính

public class Employee {
    private int id;
    private String name;
    private Date startDate;

    public Employee(Employee employee) {
        this.id = employee.id;
        this.name = employee.name;
        this.startDate = new Date(employee.startDate.getTime());
    }
}

Copy constructor vs Clone

Trong Java, chusng ta cũng có thể sử dụng clone method để tạo một object mới từ một object đã tồn tại. Tuy nhiên copy constructor có một số ưu điểm hơn clone method:

  • Copy constructor dễ triển khai hơn clone method, chúng ta không cần implement Cloneable interface và xử lý CloneNotSupportedException.
  • Clone method trả về một object có kiểu dữ liệu Object, do đó chúng ta cần phải cast nó sang kiểu dữ liệu tương ứng.
  • Chúng ta không thể gán giá trị cho một thuộc tính final trong class với clone method nhưng copy constructor thì được.

Inheritance Issues

Các subclass không thể thừa kế copy constructor của supperclass, do đó nếu chúng ta muốn khởi tạo các object của subclass con từ một superclass, chúng ta sẽ phải thực hiện cast object tương tự như khi sử dụng clone method.

Ví dụ có Manager class thừa kế từ Employee có chứa một copy constructor của riêng nó.

public class Manager extends Employee {
    private List<Employee> directReports;
    // ... other constructors

    public Manager(Manager manager) {
        super(manager.id, manager.name, manager.startDate);
        this.directReports = directReports.stream()
          .collect(Collectors.toList());
    }
}

Sau đó, chúng ta khai báo một biến Employee và khởi tạo nó bằng constructor của Manager:

Employee source = new Manager(1, "Deft Manager", startDate, directReports);

Vì kiểu tham chiếu là Employee, chúng ta phải chuyển nó sang kiểu Manager để có thể sử dụng copy constructor của Manager

Employee clone = new Manager((Manager) source);

Do vậy chúng ta có thể gây ra ClassCastException tại thời điểm runtime nếu object truyền vào không phải là một Manager object.

Có một cách để tránh ép kiểu như trên là tạo một method cho phép Manager thừa kế từ Employee 

public class Employee {
   public Employee copy() {
        return new Employee(this);
    }
}

public class Manager extends Employee {
    @Override
    public Employee copy() {
        return new Manager(this);
    }
}

Sau đó chúng ta chỉ cần triển khai như sau

Employee clone = source.copy();

Nguồn

https://www.baeldung.com/java-copy-constructor

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x