배열을 제외하고는 Cloneable 사용을 지양하는 것이 좋으며 복제 기능은 생성자와 팩터리를 이용하는 것이 좋다.
Cloneable
복제해도 되는 클래스임을 명시하는 용도의 믹스인 인터페이스 (지만 의도한 목적 이루지 못함)
믹스인 : 다른 클래스에서 사용할 목적으로 만들어진 클래스, 포함 관계
- clone 메서드가 Object에 선언됨, 심지어 protected
→ Cloneable 구현만으로 외부 객체에서 clone 메서드 호출할 수 없음
//Cloneable interface
public interface Cloneable {
}
//Object의 clone 메서드
@IntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
Cloneable 인터페이스 역할
- Object의 protected 메서드인 clone의 동작 방식을 결정한다.
- Cloneable 구현한 클래스의 인스턴스에서 clone 호출 시 복사한 객체 반환
- 구현하지 않은 클래스의 인스턴스에서 호출하면 CloneNotSupportedException 던짐
clone 메서드의 일반 규약
객체의 복사본을 생성해 반환한다.
- 다음의 식들은 일반적으로 참이지만 필수는 아니다.
- x.clone() != x
- x.clone().getClass() == x.getClass()
- x.clone().equals(x)
- 관례상 메서드가 반환하는 객체는 super.clone 호출해 얻어야 한다. 이 클래스와 모든 상위클래스가 이 관례를 따르면
- x.clone().getClass() == x.getClass() 참이다.
- 관례상, 반환된 객체와 원본 객체는 독립적이어야 한다.
제대로 동작하지 않는 Clone 메서드
Clone의 메커니즘은 생성자 연쇄와 비슷하다.