728x90
반응형
clone() of Object
함수 원형
protected Object clone() throws CloneNotSupportedException
- Shallow Copy
- 객체를 복제할 때, 원본 객체와 복제 객체는 동일한 객체를 참조
- 즉, 객체 내부에 참조 타입 필드가 있는 경우, 해당 필드의 참조는 동일하게 유지
- 변경이 한쪽 객체에 영향을 미칠 수 있음
- Deep Copy
- 객체를 복제할 때, 원본 객체와 복제 객체는 서로 독립적인 객체를 참조
- 즉, 참조 타입 필드의 복사본도 생성되어 변경이 한 쪽 객체에 영향을 주지 않음
- Cloneable 인터페이스
- Cloneable 인터페이스는 객체가 복제 가능함을 나타내기 위해 구현해야 함
- 이 인터페이스를 구현하지 않은 객체는 clone() 메서드를 호출할 때 CloneNotSupportedException 예외 발생
- clone() 메서드
- clone() 메서드는 객체를 복제하여 복제된 객체를 반환
- 접근 지정자 protected이므로, 복제를 위해 해당 클래스에서 public으로 오버라이딩
- 반환 타입은 Object이므로, 필요에 따라 캐스팅
- clone() 메서드의 오버라이딩
- 일반적으로 super.clone()을 호출하여 얕은 복사를 수행한 뒤
- 필요에 따라 참조 타입 필드에 대해 깊은 복사를 수행
- 리턴 타입을 복사한 객체 타입으로 바꿀 수 있음
예시 1
class Point implements Cloneable { // class Point만 쓰면 예외 발생
int x, y;
public Point(int x, int y) {
this.x = x; this.y = y;
}
@Override
public String toString() {
return "Point(" + x + "," + y + ")";
}
@Override
public Object clone() throws CloneNotSupportedException {
Object o = super.clone(); // 객체 복제
System.out.println(o.getClass().getName());
return o;
}
}
public class Main {
public static void main(String[] args) {
Point p1 = new Point(2, 4);
System.out.println(p1);
try {
Point p2 = (Point)p1.clone();
System.out.println(p2);
System.out.println(p1 == p2 ? true : false); // 서로 다른 객체면 false
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
Point(2,4)
Point
Point(2,4)
false
예시 2
class Point implements Cloneable {
int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
@Override
public String toString() { return "Point(" + x + "," + y + ")"; }
@Override
public Point clone() throws CloneNotSupportedException { // 리턴 타입 Point
return (Point) super.clone();
}
}
class Circle implements Cloneable {
Point center;
int radius;
Circle(Point center, int radius) {
this.center = center;
this.radius = radius;
}
void setCenter(int x, int y) {
this.center.x = center.y = y;
}
void setRadius(int radius) {
this.radius = radius;
}
@Override
public String toString() {
return "Circle(center=" + center + "radius=" + radius + ")";
}
@Override
public Circle clone() throws CloneNotSupportedException { // 리턴 타입 Circle
Circle c = (Circle) super.clone(); // 얕은 복사
c.center = center.clone(); // 필드의 객체까지 복사하므로 깊은 복사가 됨
return c; // 깊은 복사 리턴
}
}
public class Main {
public static void main(String[] args) {
try {
Circle c1 = new Circle(new Point(3, 4), 2);
System.out.println(c1);
Circle c2 = c1.clone(); // 리턴 타입 변경으로 인해 캐스팅 불필요
System.out.println(c2);
c2.setCenter(30, 40); // 깊은 복사이므로 c1값은 바뀌지 않음
c2.setRadius(20); // 깊은 복사이므로 c1값은 바뀌지 않음
System.out.println(c1);
System.out.println(c2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
Circle(center=Point(3,4)radius=2)
Circle(center=Point(3,4)radius=2)
Circle(center=Point(3,4)radius=2)
Circle(center=Point(40,40)radius=20)
728x90
반응형
'전공 > 객체지향프로그래밍' 카테고리의 다른 글
[객체지향프로그래밍][Java] Nested Classes (0) | 2023.06.10 |
---|---|
[객체지향프로그래밍][Java] Exception Handling (0) | 2023.06.07 |
[객체지향프로그래밍][Java] Initialization (정적 초기화 블록, 인스턴스 초기화 블록) (0) | 2023.06.07 |
[객체지향프로그래밍][Java] Generics 심화 내용 (0) | 2023.06.03 |
[객체지향프로그래밍][Java] Queue 심화 내용 (0) | 2023.06.01 |