객체 복제를 위한 Object의 clone 메서드는 가장 널리 쓰이는 Clonable 인터페이스를 구현하는 방법을 이용해 사용된다.
그러나 clone 메서드는 허술한 일반 규약을 갖고 있고, 완벽히 복제되었으면서 완전히 다른 객체를 생성하는 메서드이기에 재정의 시 주의가 필요하다.
clone 메서드 재정의
값, 불변 객체 필드만 갖고 있다면 super.clone을 통해 clone 메서드를 구현할 수 있다.
가변 객체 필드를 갖는 다면 super.clone은 shallow copy 를 제공하기 때문에 적절하지 않다.
따라서 해당 객체의 clone 메서드를 호출해서 가져오거나, deep copy 를 따로 구현하는 등의 추가적인 조작이 필요하다.
가변 객체 필드가 final이라면 어떨까? clone 메서드를 이용하더라도 필드에 직접 값을 넣어줄 수 없다.
따라서, 가변 객체를 참조하는 필드는 final 로 선언하라
는 일반 용법과 Cloneable 아키텍처는 충돌한다
더 나은 객체 복사 방식
복사 생성자: public Yum(Yum yum) = {...};
복사 팩터리: public Yum newInstance(Yum yum) = {...};
핵심 정리
복제 기능은 생성자와 팩터리를 이용하자. 단, 배열만은 clone 메서드 방식이 가장 깔끔한, 이 규칙의 합당한 예외이다.