Closed cheewr85 closed 2 years ago
자바 리플렉션는 구체적인 클래스 타입을 알지 못하더라도 그 클래스의 메소드와 타입 그리고 변수들을 접근할 수 있도록 해주는 자바 API임
그러면 이 리플렉션 자체가 Cloneable을 그리고 정확히 알지 못하더라도 리플렉션의 성질을 활용해서 clone 메서드를 호출해서 접근할 수 있는 것임
먼저 일반적으로 clone을 재정의를 아래와 같이 함
public class Example {
public Example() {
Node node = new Node();
Node node1 = node.clone();
// node과 node1의 해쉬 코드는 다르므로 서로 다른 클래스로 복제가 되었다.
System.out.println(node.hashCode());
System.out.println(node1.hashCode());
}
public static void main(String[] args) {
new Example();
}
}
// clone 함수를 사용하기 위해서는 Cloneable 인터페이스를 상속받는다. class Node implements Cloneable { private String data;
public void setData(String data) { this.data = data; }
public void print() { System.out.println(data); }
// clone을 재정의한다. @Override public Node clone() { try { // clonable 인터페이스를 상속받으면 복제함수를 사용할 수 있다. return (Node) super.clone(); } catch (Throwable e) { return null; } } }
- 하지만 여기서 리플렉션을 통해서 재정의 가능함
```java
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Example {
// 클래스 복제
public Object clone(Object obj) {
try {
// 복제할 클래스 타입을 취득한다.
Class<?> clz = obj.getClass();
// 복제할 클래스의 생성자를 취득한다.
Constructor<?> cons = clz.getDeclaredConstructor();
// 클래스를 생성한다.
Object clone = cons.newInstance();
// 클래스 내부의 변수를 취득한다.
for (Field field : clz.getDeclaredFields()) {
// private, protected 접근자도 접근할 수 있게 바꾼다.
field.setAccessible(true);
// 원본 클래스로부터 데이터를 취득한다.
Object data = field.get(obj);
// 복제할 클래스로 데이테를 입력한다.
field.set(clone, data);
}
// 복제된 클래스를 리턴한다.
return clone;
} catch (Throwable e) {
return null;
}
}
public Example() {
// 클래스 생성
Node node = new Node();
// Data를 넣는다.
node.setData("Hello world");
// 클래스 복제
Node node1 = (Node) clone(node);
// 해쉬 코드가 다르니 서로 다른 클래스이다.
System.out.println(node.hashCode());
System.out.println(node1.hashCode());
// 복제된 클래스에도 데이터가 잘 들어가 있다.
node1.print();
}
public static void main(String[] args) {
new Example();
}
}
class Node {
private String data;
public void setData(String data) {
this.data = data;
}
public void print() {
System.out.println(data);
}
}
[질문] 77pg
리플렉션(아이템 65)이 뭔가요? 리플렉션을 어떻게 사용하면 Cloneable을 구현하는 것만으로도 외부에서 clone 메서드를 호출할 수 있나요?