오늘은 Object 클래스 내에 있는 clone 메서드에 대하여 공부해보았습니다.
실제로 자주 사용하진 않는다고 들었지만 그 기능에 대하여 알아두는 것이 좋을 것 같아 간단한 예시 코드들을 통해 공부해보았습니다.
1. clone() 메서드
clone 메서드는 원본 객체의 필드값과 동일한 값을 가지는 새로운 객체를 생성합니다. 즉 한마디로 말하면 복제하는 메서드입니다. 여러 정보를 담고 있는 객체가 있는데, 그 객체의 clone 메서드를 사용하면 같은 정보를 담고 있는 또 다른 하나의 객체를 만들 수 있습니다. 또한 복제하는 이유는 원본 객체를 안전하게 보호하기 위해서입니다.
하지만 모든 클래스가 복제가 가능한 것은 아닙니다. clone은 Cloneable 인터페이스의 추상 메서드이기 때문에
재정의 한 clone 메서드를 사용하기 때문에(이유는 Object 클래스내의 clone 메서드는 protected로 선언되어있기 때문에 public으로 재정의하여 메서드를 사용하기 때문입니다.) Cloneable 인터페이스가 구현된 클래스여야만 복제가 가능합니다.
clone()메서드를 호출할 때 CloneNotSupportedException 예외가 발생하며 이 예외를 위해선 try catch 구문이 필요합니다.
※ clonepractice 클래스(예시 코드로 clone 메서드를 활용해 보았습니다.)
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
|
package Clone;
import java.util.Calendar;
public class clonepractice {
public static void main(String[] args) {
// TODO Auto-generated method stub
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(2020, 9, 10);
System.out.print("(calendar)오늘의 날짜: ");
System.out.println(calendar.get(Calendar.YEAR) + "년 " + calendar.get(Calendar.MONTH) + "월 "
+ calendar.get(Calendar.DAY_OF_MONTH)+"일");
//clone을 이용하여 Clonecal객체에 calendar객체 복제하기
Calendar Clonecal = (Calendar) calendar.clone();
System.out.print("(Clonecal)오늘의 날짜: ");
System.out.println(Clonecal.get(Calendar.YEAR) + "년 " + Clonecal.get(Calendar.MONTH) + "월 "
+ Clonecal.get(Calendar.DAY_OF_MONTH)+"일");
}
}
|
cs |
● clonepractice 코드 실행 결과
Calendar 클래스로 객체를 생성하여 clone 메서드를 활용해 본 코드의 실행 결과입니다. 코드를 보시면 calendar에 입력한 데이터가 clone메서드를 통해 복제되어 Clonecal에도 출력되는 것을 볼 수 있습니다.
즉 값이 그대로 복제 된 것입니다.
2. Cloneable 인터페이스를 사용하여 clone 메서드를 직접 사용해보기
이번엔 Cloneable 인터페이스를 사용하여 직접 만든 클래스에서 사용해보았습니다. 먼저 cloneablepractice라는 클래스를 만들어줍니다. 이 클래스는 clone 메서드를 사용하기위한 준비작업으로 복제를 하기 위해서는
Cloneable 인터페이스를 구현하고 clone 메서드를 재정의 해야 하기 때문에(상위클래스의 clone을 return 하여 연결, CloneNotSupportedException예외를 메서드 밖으로 던져줌) Name이라는 변수를 return하도록 하여 만든 클래스입니다.
A. cloneablepractice 클래스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package Clone;
//clone 메소드를 사용하기위한 준비작업
//복제를 하기 위해서는 Cloneable 인터페이스를 구현하고 clone 메소드를 재정의 해야합니다.
public class cloneablepractice implements Cloneable {
private String Name;
public cloneablepractice(String name) {
Name=name;
}
public String getName() {
return Name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
|
cs |
B. cloneabletest 클래스
cloneablepractice 클래스로 test1과 test2라는 2개의 객체를 생성하였습니다. test1 객체에는 kobalja라는 데이터를 직접 입력하였고 test2 객체는 test1으로부터 clone 메서드를 통해 객체 복제를 하였습니다.
두 객체의 실행 결과는 어떻게 될까요? 답은 두 객체의 이름 즉, Name 값을 출력 하였을때 같은 출력값을 가지고 있는 것을 확인 할 수 있습니다.
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
|
package Clone;
import java.util.Calendar;
public class cloneabletest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//clonablepractice 클래스로 2개의 객체(test1,test2)생성
//test1객체는 직접메모리에 "kobalja"라는 데이터를 입력
cloneablepractice test1 = new cloneablepractice("kobalja");
cloneablepractice test2 = null;
//test2객체는 test1클래스로부터 clone메서드를 이용해 객체를 복제
try {
test2 = (cloneablepractice) test1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
//그 후에 결과를 보면 test1과 test2 둘다 같은 출력값을 가진 것을 확인 할 수 있음
System.out.println("test1의 이름: "+test1.getName());
System.out.println("test2의 이름: "+test2.getName());
}
// 1.
// 하지만 protected로 정의 되어 있기 때문에 public으로 재정의해서 사용해야 합니다. 결론은 본질적으로 // clone 메서드는 또다른 종류의 생성자나 마찬가지입니다. // 그래서 Cloneable 인터페이스가 구현된 클래스에서 사용 가능합니다.(재정의한 걸 사용하기 때문) // 2. clone 메서드를 통해 객체의 복제가 가능하다.
}
|
cs |
● cloneabletest 코드 실행 결과
★ clone() 메서드 정리
1. clone 메서드는 원본 객체의 필드값과 동일한 값을 가지는 새로운 객체를 생성한다.(객체의 복제가 가능하다.)
2. 복제이유: 원본객체를 안전하게 보호하기 위해서이다.
3. Cloneable 인터페이스를 구현하지 않으면 clone()메소드를 호출할 때 CloneNotSupportedException예외가 발생하므로 Cloneable 인터페이스가 구현된 클래스에서만 사용이 가능하다.
4. 예외를 잡기 위해서는 try-catch 구문이 필요하다.
최근댓글