(Effective Java) clone을 재정의 할때는 신중하라

* Cloneable 인터페이스에는 clone 메소드가 없으며, Object의 clone 메소드는 protected로 선언되어 있다.

*Cloneable 인터페이스에 아무런 메소드가 없다면 대체 Cloneable이 하는일은 무엇인가?
->protected로 선언된 Object의 clone 메소드가 어떻게 동작할지 정한다.
-> 만일 어떤 클래스가 Cloneable을 구현한다면, Object의 clone메소드는 해당 객체를 필드단위로 복사한 객체를 반환한다.

*일반적으로 인터페이스를 구현한다는 것은 클래스가 무슨 일을 할 수 있는지 클라이언트에게 알리는 것이다. 그런데 Cloneable의 경우에는 상위 클래스의 protected멤버가 어떻게 동작할지 규정하는 용도로 쓰이고 있다.


*clone 메소드의 일반규약은 느슨하다. java.lang.Object 명세를 보면 다음과 같다.


  • 객체의 복사본을 만들어서 반환하다. "복사"의 정확한 의미는 클래스마다 다르다. 일반적으로는 다음의 조건이 충족되어야 한다. 객체 x가 있다고 하자.
-> x.clone() != x는 참이어야 한다.

  • x.clone().getClass() == x.getClass() 는 참이 되겠지만, 반드시 그래야 하는것은 아니다.
  • x.clone().equals(x)  이것도 실행한 결과가 true가 되겠지만, 반드시 그래야 하는것은 아니다.


* 사실상 clone 메소드는 또 다른 형태의 생성자다. 원래 객체를 손상시키는 일이 없도록 해야하고, 복사본의 불변식(invariant)도 제대로 만족시켜야 한다.
만약 스택을 복사하려면 스택의 내부구조도 복사해야 한다.





-> elements.clone() 호출 결과를 Object[] 로 형변환 할 필요가 없음에 유의하자.
릴리즈 1.5버전부터는 배열에 clone을 호출하면 반환되는 배열의 컴파일 시점자료형은 복제 대상 배열의 자료형과 같다.

위의 해법에서 elements 필드가 final 로 선언되어 있으면 동작하지 않는 다는 것에 유의하자.
clone의 아키텍처는 변경 가능한 객체를 참조하는 final필드의 일반적 용법과 호환되지 않는다.


* 해쉬테이블의 복사에서




->리스트가 길게되면 스택오버플러가난다. 그러므로 이러한 재귀방법은 좋지않다.

대신..




댓글

이 블로그의 인기 게시물

(ElasticSearch) 결과에서 순서 정렬

(네트워크)폴링방식 vs 롱 폴링방식

(18장) WebSocekt과 STOMP를 사용하여 메시징하기