Last updated
Last updated
해당 인스턴스의 복사본을 만들어 반환하는 메서드
물리적 주소는 다르나, 동일한 클래스의 인스턴스이며 equals로 비교했을 때 같은 객체를 생성
clone 메서드는 protected이기 때문에 사실상 이 메서드는 외부에서 접근이 불가능
때문에, Java에서는 Cloneable
이라는 인터페이스를 제공해 이를 구현하는 클래스는 clone 메서드를 제공
Cloneable
이 clone 메서드를 오버라이딩하도록 강제하는 인터페이스는 아님에 주의
Cloneable
의 올바른 사용 예clone 메서드를 public으로 재정의하고, 해당 클래스를 반환하도록 함
반드시 super.clone()을 호출해야 함
모든 하위 클래스에서 이 규약을 지킨다면, 참조형을 제외한 필드들은 모두 잘 복사됨이 보장됨
하지만 참조형 필드는 얕은 복사가 일어날 수 있음
복잡한 가변 데이터 묶음을 갖는 클래스의 경우 clone 메서드의 오버라이딩이 단순히 super.clone()으로 끝나지 않으며, 이후에 이 가변 필드들을 재귀적으로 복사하는 일을 수행해야 함
불변 데이터는 초기화 후 변경이 불가하므로 아예 복사가 어려움
불변 참조형 필드(final reference field)가 포함된 클래스를 완전히 복사하려면 final 한정자를 제거해야 함
위와 같은 사유로 Cloneable
을 구현하여 clone 메서드를 오버라이딩하는 방식은 권장되지 않으며, 복사 생성자 또는 복사 팩터리(정적 메서드) 방식으로 대체할 것을 권고
복사 생성자는 자신과 같은 클래스의 인스턴스를 매개변수로 받아 필드들을 직접 세팅(복사)함
복사 생성자에 Item 1
(생성자 대신 정적 팩토리 메서드) 패턴을 적용한 경우에 해당
초기화 단계에 해당하므로 불변 필드들을 복사하는 것이 가능
Cloneable
과 clone 메서드는 문서화된 규약에 의존하기 때문에 클라이언트가 이 규약을 지키지 않을 수 있다는 위험이 있는데, 위의 두 방식은 그러한 위험이 없음
Cloneable
을 구현해도 clone 메서드를 오버라이딩하도록 강제하지 않음
super.clone()을 반드시 호출해야 함에도, 이를 강제하지 않음
반드시 같은 클래스의 인스턴스를 받지 않아도 됨. 해당 클래스가 구현한 인터페이스를 매개변수로 전달받아도 됨