- **복제해도 되는 클래스**임을 명시
- 구현(implements)하지 않고 `clone()` 메소드 사용 시 `CloneNotSupportedException`
- 구현 후 `clone()` 호출 시 객체의 필드를 하나하나 복사한 객체 반환
상위 클래스가 제대로 동작하는 clone 메서드를 가지며 Cloneable을 구현해줄 때
-
상위 객체의
clone() 메서드
를 호출- 바로 원본의 복사본을 얻을 수 있다.
리턴 타입
이부모 메소드의 리턴 타입의 자식
인 경우 리턴 타입을 변경 가능하다.- Object에서는 Object 타입을 리턴해 준다.
- Crew 클래스에서는 편의를 위해 Crew 타입을 리턴하도록 변경
- 부모 메소드의
접근제한자를 확장 가능
하다.- Object에서는 protected로 선언되어 있다.
- Crew 클래스에서는 clone()를 모두 사용할 수 있도록 public 제한자로 변경
class Crew implements Cloneable{
String course;
String name;
public Crew(String course, String name) {
this.course = course;
this.name = name;
}
@Override
public Crew clone() {
try {
return (Crew)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
-
문제점
Clone()의 결과로
같은 객체를 참조
하게 되어 문제 발생 -
해결 방안
- 상위 객체의
clone()
메서드를 호출 - 참조 필드에 대해서 복사 진행
- 상위 객체의
int[] numbers;
...
@Override
public Lotto clone() {
try {
Lotto clonedLotto = (Lotto)super.clone();
clonedLotto.numbers = numbers.clone();
return clonedLotto;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
-
복사 생성자 / 복사 팩터리
- 자신과 같은 클래스의 인스턴스를 인수로 받는 생성자 / 메서드
public Lotto() { numbers = new int[]{1, 2, 3, 4, 5, 6}; } // 복사 생성자 public Lotto(Lotto lotto) { // 매개변수에 있는 lotto의 값들로 현재 인스턴스를 채워준다. super(); setLotto(lotto.numbers); } // 복사 팩터리 public static Lotto newInstance(Lotto lotto) { // 매개변수에 있는 lotto의 값들로 채워진 인스턴스를 반환 Lotto instance = new Lotto(); instance.setLotto(lotto.numbers); return instance; } public void setLotto(int[] targetNumbers) { for (int i = 0; i < 6; i++) { numbers[i] = targetNumbers[i]; } }
-
인터페이스 타입의 인스턴스를 인수로 받을 수 있다는 장점이 있다.
- Collection 변환에 사용된다.
public static void main(String[] args) { List<Integer> list = List.of(1, 2, 3, 4); List<Integer> arrayList = new ArrayList<>(list); // 복사 생성자 }
기본 원칙으로는 복제 기능은 생성자와 팩터리를 이용하는 것이 가장 좋으며, 배열의 경우는 예외로 clone 메서드가 가장 깔끔하다.
참고 자료
[https://velog.io/@roro/Java-Object-클래스-clone](https://velog.io/@roro/Java-Object-%ED%81%B4%EB%9E%98%EC%8A%A4-clone)
[https://blog.geunho.dev/posts/java-deep-copy-shallow-copy/](https://blog.geunho.dev/posts/java-deep-copy-shallow-copy/)
[https://bitsoul.tistory.com/55](https://bitsoul.tistory.com/55)