Study-Mornda / Effective-Java

'Effective Java 3/E' 스터디 저장소입니다.
3 stars 0 forks source link

[아이템 13-질문] 리플렉션 #52

Closed cheewr85 closed 2 years ago

cheewr85 commented 2 years ago

[질문] 77pg

리플렉션(아이템 65)이 뭔가요? 리플렉션을 어떻게 사용하면 Cloneable을 구현하는 것만으로도 외부에서 clone 메서드를 호출할 수 있나요?

cheewr85 commented 2 years ago

// 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);
  }
}

참고

리플렉션 리플렉션 구현 예제