book review/Effective java
[Effective Java] Item 13. clone 재정의는 주의해서 진행하라
dobidugi
2024. 7. 1. 07:45
Cloneable 인터페이스
Java에는 Cloneable이라는 믹스인 인터페이스가 존재가 있다.
해당 인터페이스를 찾아보면 아무것도 없는걸 볼 수 있는데, 해당 인터페이스의 용도는 Cloneable 인터페이스로 구현된 클래스에서 clone메서드를 호출할때 안전하게 Object.clone()메서드가 해당 클래스의 필드를 복사 할 수 있음을 나타낸다.
만약 Cloneable을 사용하지않는 클래스에서 clone을 호출하게된다면 CloneNotSupportException을 발생시킨다.
clone 메소드의 규약
clone 메서드가 usper.clone이 아닌, 생성자를 호출해 얻은 인스턴스를 반환해도 컴파일러는 불평하지 않음
clone을 재정의한 클래스가 final이라면 걱정해야 할 하위 클래스가 없으니 아래 관례는 무시해도 된다.
x.clone != x // 이 식은 참이다
x.clone().getClass == x.getClass() // 이 식은 참이지만 반드시 만족해야하는건 아님
// 관례상 이 메소드가 반환하는 객체는 super.clon을 호출해 얻어야함
x.clone().getClass().equals(x) // 이 식은 참이지만 필수는 아님
x.clone().getClass() == x.getClass()
// 관례상 반환된 객체와 원본 객체는 독립적이여야함
// 이를 만족하려면 super.clone으로 얻은 객체의 필드 중 하나 이상을 반환 전에 수정해야할 수 있음
재 정의시 문제점
가변 상태를 참조하는 클래스용 clone 메서드 에서의 문제
@Override public Stack clone() {
private Object[] elements;
@Override public Stack clone(){
try {
Stack result = (Stack) super.clone();
result.elements = elements.clone();
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
이런식으로 복사하지않으면 elements의 참조 주소를 복사하게되며 이렇게될 경우 원본값이 변경되면 복사본값도 변경될 수 있기때문에 조심 해야함
HashTable 복제
/* TODO */
마무리
사실상 clone 메서드는 생성자와 같은 효과를내며 원본 객체에 아무런 해를 끼치지않는동시에 복제된 객체의 불변을 보장해야함