Item 13. Clone 재정의는 주의해서 진행하라

Jiyeong·2022년 9월 27일
0

Effective Java

목록 보기
4/14

애매모호한 clone 규약

  • clone 규약
    x.clone() != x 반드시 true
    x.clone().getClass() == x.getClass() 반드시 true
    x.clone().equals(x) true가 아닐 수도 있다.

  • 불변 객체라면 다음으로 충분하다.

  • Cloneable 인터페이스를 구현하고, clone 메서드를 재정의한다.
    이때 super.clone()을 사용한다.

가변 객체의 clone 구현하는 방법

  • 접근 제한자는 public, 변환 타입은 자신의 클래스로 변경.

deepCopy - 배열을 직접 만든 후, 하나씩 배열을 만들어 넣어 준다.
재귀적으로 만드면 stack이 쌓여서 스택오버플로우가 생길 수도 있다.
shallowCopy - 배열 안에 있던 코드를 동일하게 참조하고 있음

가변 객체 clone할 때 주의사항

clone() 안에서 다른 메서드를 호출할 때

  • 추상 객체를 구현할 때는 Cloneable 인터페이스를 구현하지 않는 게 좋다.
  • synchronized까지 붙여야 정석적인 clone() 메서드 사용 방법
  • 생성자를 써서 clone하기
  • final을 쓸 수 없다.

clone 대신 권장하는 방법

  • "복사 생성자" 또는 변환 생성자, "복사 팩터리" 또는 변환 팩터리
  • 생성자를 쓰지 않으며, 모호한 규약, 불핋요한 검사 예외, final 용법 방해 등에서 벗어날 수 있다.
  • 또 다른 큰 장점 중 하나로 인터페이스 타입의 인스턴스를 리턴할 수 있다.
    - 클라이언트가 복제본의 타입을 결정할 수 있다.
    *참고) Josh Bloch on Design, "Copy Constructor"

완벽 공략

  • p80. 비검사 예외(UnChecked Exception)였어야 했다는 신호다.
  • p81. HashTable과 LinkedList
  • p83. deep copy
  • p83. 리스트가 길면 스택 오버플로를 일으킬 위험이 있기 때문이다.
  • p85. clone 메서드 역시 적절히 동기화해줘야 한다.
  • p86. TreeSet

Unchecked Exception

  • RuntimeException
  • Error를 상속받은 Exception

왜 비검사 예외를 선호하는가?

  • 컴파일 에러를 신경 쓰지 않아도 된다.
  • try-catch로 감싸거나 메서드 선언부에 선언하지 않아도 된다.
  • 검사 예외가 있는 이유 : 클라이언트에게 잡지 않은 예외를 알려줄 수 있기 때문이다.

언제 어떤 예외를 써야하는가?

  • 단순히 처리하기 쉽고 편하다는 이유만으로 RuntimeException을 사용하지 말 것.
  • 가이드라인 : 클라이언트에게 복구할 수 있는 예외라면 CheckedException을 사용하고, 해당 예외 발생 시 아무것도 할 수 없다면 비검사 예외를 만든다.

TreeSet

AbstractSet을 확장한 정렬된 컬렉션

  • 엘라먼트를 추가한 순서는 중요하지 않다.
  • 엘리먼트가 지닌 자연적인 순서(natural order)에 따라 정렬한다.
  • 오름차순으로 정렬한다.
  • 스레드 안전하지 않다.
  • 과제) 이진 검색 트리, 레드 블랙 트리 학습

Binary Search Tree

이진 탐색 트리 : 이진트리(각 노드의 자식 노드가 최대 2개인 트리)를 갖는 트리이다.

  1. 각 노드에 중복되지 않는 키(key)가 있다.
  2. 루트 노드의 왼쪽 서브 트리는 해당 노드의 키보다 작은 키를 갖는 노드들로 이루어져 있다.
  3. 루트 노드의 오른쪽 서브 트리는 해당 노드의 키보다 큰 키를 갖는 노드들로 이루어져 있다.
  4. 좌우 서브 트리도 모두 이진 탐색 트리여야 한다. 

출처: https://code-lab1.tistory.com/10 [코드 연구소:티스토리]

Red Black Tree

레드 블랙 트리 : 자가 균형 이진 탐색 트리이다.

  1. 모든 노드는 빨간색 혹은 검은색이다.
  2. 루트 노드는 검은색이다.
  3. 모든 리프 노드(NIL)들은 검은색이다. (NIL : null leaf, 자료를 갖지 않고 트리의 끝을 나타내는 노드)
  4. 빨간색 노드의 자식은 검은색이다.   == No Double Red(빨간색 노드가 연속으로 나올 수 없다)
  5. 모든 리프 노드에서 Black Depth는 같다.   == 리프노드에서 루트 노드까지 가는 경로에서 만나는 검은색 노드의 개수가 같다.

출처: https://code-lab1.tistory.com/62 [코드 연구소:티스토리]

TreeSet은 내부적으로 TreeMap(정렬된 맵)이란 걸 사용한다.

profile
깃스타가 되고 싶은 벨플루언서

0개의 댓글