티스토리 뷰

Java/Effective Java

[Item13] Cloneable 금지

ryumodern 2022. 2. 20. 00:41

Cloneable은 mixin interface라고 한다, 믹스인 인터페이스가 무엇일까?

Item20에서 자세히 설명되어 있는데 A라는 클래스가 있다면 Cloneable과 같은 mixin interface를 구현하게 하면

A 클래스가 가진 본연의 기능에 다른 기능을 덧붙이기 때문에 (mix-in) 믹스인이라고 한다

 

두 번째 코멘트를 보자

자바에서는 인터페이스에 상태나 코드를 가질 수 없어 믹스인 인터페이스란 건 없다고 하며

추상 클래스를 이용했다면 다중 상속을 지원하지 않기에 모든 조건을 만족할 수 없다고 했다

 

https://stackoverflow.com/questions/17987704/an-example-of-a-mixin-in-java

 

자바8 이후로 인터페이스에서 메서드 구현이 가능하므로 이제는 믹스인 인터페이스가 존재할 수 있다

그럼에도 Cloneable은 정상적인 믹스인 인터페이스라고 할 수 없는데

clone() 메서드를 직접 제공하는 게 아니라 Object가 가진 clone()의 동작 방식을 결정하기 때문이다

자바 디자인 실패 사례 중 하나로써 따라하지 말아야 할 방식 중 하나라고 한다

 

 

Cloneable을 활용해 복사 가능한 클래스임을 명시했다면 clone을 재정의해주어야 한다

복제 가능하다고 선언한 클래스에 있는 필드들로 새로운 객체를 만들어 반환해주면 되는데

이때 shallow copy, deep copy를 주의하도록 하자

참조 타입의 경우는 반드시 deep copy로 값을 복사해 넘겨야 한다

그렇지 않은 경우 참조 타입의 메모리 주소를 넘긴 것이므로 연결이 끊어지지 않은 상태다

또한 공변 반환 타입을 이용해서 기본 구현 상태로 반환하지 말고 Object -> 커스텀 클래스 형태로 반환해주고

CloneNotSupportedException은 Checked Exception이기 때문에 재정의한 메서드에서 지워주도록 하자

// 노노
@Override
protected Object clone() throws CloneNotSupportedException {
  return super.clone();
}

// 굿
@Override
protected MyClass clone() {
  return (필드 복사한 새로운 객체);
}

 

Cloneable을 구현한 클래스 작성 시 아래와 같은 부분을 신경 써야 한다

1. shallow, deep copy 주의

2. 반환 타입 변경

3. CloneNotSupportedException 없애기

4. 상속을 위한 클래스라면 clone 퇴화 시키기

5. 멀티 스레드에서 사용한다면 동기화 주의

 

Cloneable을 사용할 때의 장점이라면 일반화된 방식으로 클래스를 만들 수 있다는 점일 것 같다

Cloneable 인터페이스로 복사 가능한 클래스임을 명시적으로 알렸으니 이 클래스를 사용하는 이는

clone()을 사용할 것이고 사용자가 기대한 대로 동작하게 해주면 된다

다만 주의점들을 전부 신경 쓸게 아니라면 복사된 객체가 필요할 때 단순하게 직접 필드 복사 메서드를 만들어서 제공하자

댓글
링크
글 보관함
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Total
Today
Yesterday