[Effective Java] Item13 - clone 재정의는 주의해서 진행하라

지구🌍·2023년 2월 19일
0

Effective Java 공부

목록 보기
4/12
post-thumbnail

clone이 뭘까...? git clone도 아니고.

Cloneable 인터페이스

복제해도 되는 클래스임을 명시하는 믹스인 인터페이스

💡믹스인 : 다른 클래스의 부모클래스가 되지 않으면서 다른 클래스에서 사용할 수 있는 메서드를 포함하는 클래스
'상속' 이 아닌 '포함'

clone 메소드: 원본 객체의 필드 값과 동일한 값을 가지는 새로운 객체를 생성해주는 메소드

clone 메소드를 사용하기 위해서는 해당 클래스에서 Cloneable 인터페이스를 구현해야 사용할 수 있다.

일반적인 사고라면? Cloneable 인터페이스에 clone 메소드가 있겠지라고 생각하겠지만 아님!!!!!

clone 메소드가 있는 곳은 Object이고, protected이며, Override 해주어야만 사용 가능하다.

Cloneable 인터페이스는 Objectclone 메소드의 동작 방식을 결정한다.
객체를 복사할 지, CloneNotSupportedException으로 던질지를 결정

이런 이상한 Cloneable 를 사용 방식

  • clone 메소드는 모든 클래스에서 오버라이딩 할 수 있다.
  • Cloneable 인터페이스를 구현한 클래스만 사용 가능하다.
  • Cloneable 은 상위 클래스 Object에 정의된 clone() 의 동작방식을 변경한다는 의미이다.

허술한 clone 메소드의 일반 규약

  1. x.clone() != x
    복사한 객체는 원본 객체와 독립적이다.
  2. x.clone().getClass() == x.getClass()
    복사한 객체와 원본 객체는 같은 클래스이다.
    반드시 만족해야하는 것은 아니다.
  3. x.clone().equals(x)
    clone()super.clone() 을 통해 객체를 얻어서 반환한다.
    일반적으로 참이지만, 필수는 아니다.

주의사항

  1. Cloneable 을 구현하면, clone() 을 재정의해야 한다.
  2. 접근자는 public, 반환형은 자기자신의 타입으로 변경한다.
  3. 공변 변환 타이핑을 통해 자기자신의 타입을 반환한다.
  4. super.clone() 으로 복제 한다.
  5. 깊은 복제 방식으로 가변 참조 객체를 복사한다.

결론

배열만이 clone()을 제대로 사용하는 유일한 예이다.
복사하는 대상이 배열이 아니라면 복사 생성자, 복사 팩터리가 더 좋다.

복사 생성자

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack(Stack s) {
        this.elements = s.elements.clone();
        this.size = s.size;
    }
}

복사 팩토리

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public static Stack newInstance(Stack s) {
        return new Stack(s.elements, s.size);
    }
}

🎈귀중한 참고자료🎈
참고자료1

profile
일취월장 하며 성장! 중! 공부한 것을 기록하자(^∀^●)ノシ

0개의 댓글