clone() nằm ở Object nhưng cơ chế rối:
- Cloneable là marker rỗng — không hề khai báo method clone(). Nó chỉ bật cờ để Object.clone() khỏi ném CloneNotSupportedException. Một interface không định nghĩa hành vi → phản trực giác.
- Object.clone() copy nông (shallow): chỉ sao field bề mặt; field tham chiếu (list, mảng, object lồng) vẫn dùng chung → sửa bản clone làm hỏng bản gốc.
- Không gọi constructor, khó dùng với field final, phải cast thủ công.
class Team implements Cloneable {
List<String> members;
@Override public Team clone() throws CloneNotSupportedException {
Team t = (Team) super.clone();
t.members = new ArrayList<>(members); // deep-copy thủ công từng field
return t;
}
}Thay thế (khuyên dùng):
- Copy constructor: new Team(other) — rõ ràng, hỗ trợ final.
- Static factory: Team.copyOf(other).
- Object bất biến thì không cần clone.
(Effective Java Item 13 — "override clone judiciously"; thực tế nên tránh Cloneable cho API mới.)