티스토리 뷰

반응형

리플렉션 ( java.io.reflect )

  • 리플렉션 기능을 이용하면 임의의 클래스에 접근할 수 있다.
    • 자바 클래스파일 정보는 컴파일되면 클래스파일로 변환되어 메모리의 Static 영역에 위치
    • Static 영역의 정보는 언제든지 접근할 수 있기 때문에 클래스의 이름만 알면 정보들을 가져올 수 있음
  • Class 객체가 주어지면 그 클래스의 생성자, 메섣, 필드에 해당하는 인스턴스를 가져올 수 있음
    • 인스턴스들로 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있음
    • 인스턴스를 이용하여 각각에 연결된 생성자, 메서드, 필드 조작 가능 (해당 클래스 인스턴스 생성, 메서드 호출, 필드 접근 등 가능)
      // 클래스 얻기 
      Class<?> class = Class.forName(); 
      
      //생성자 얻기 
      Constructor<?> constructor = class.getDeclaredConstructor(); 
      
      // 클래스 인스턴스 만들기 
      constructor.newInstance();

 

 

리플렉션의 단점

  • 컴파일타임 타입 검사가 주는 이점을 누릴 수 없음
    • 예외 검사도 마찬가지
    • 리플렉션으로 존재하지 않는 or 접근할 수 없는 메서드를 호출하려한다면 런타임 오류 발생
  • 코드가 지저분하고 장황해짐
  • 성능이 떨어짐

→ 리플렉션은 아주 제한된 형태로만 사용해야 단점을 피하고 이점만 취할 수 있다.

컴파일타임에 이용할 수 없는 클래스를 사용해야만 하는 경우라면 리플렉션은 인스턴스 생성에만 쓰고 이렇게 만든 인스턴스는 인터페이스나 상위 클래스를 참조해 사용하자.

 

 

리플렉션을 이용한 인스턴스 생성

public static void main(String[] args) {
    Class<? extends Set<String>> cl = null;
    try {
        // 여기서 args[0] 의 인자에 의해 클래스가 결정된다.
        // args[0] 이 무엇인지에 따라 동작이 달라진다.
        cl = (Class<? extends Set<String>>) Class.forName(args[0]);
    } catch (ClassNotFoundException e) {
        fatalError("클래스를 찾을 수 없습니다 !!");
    }

    Constructor<? extends Set<String>> cons = null;
    try {
        cons = cl.getConstructor();
    } catch (NoSuchMethodException e) {
        fatalError("매개변수없는 생성자가 없습니다 !!");
    }

    Set<String> s = null;
    try {
        s = cons.newInstance();
    } catch (IllegalAccessException e) {
        fatalError("생성자에 접근할 수 없습니다.");
    } catch (InstantiationException e) {
        fatalError("클래스를 인스턴스화할 수 없습니다.");
    } catch (InvocationTargetException e) {
        fatalError("생성자가 예외를 던졌습니다." + e.getCause());
    } catch (ClassCastException e) {
        fatalError("Set 을 구현하지 않은 클래스입니다.");
    }

    s.addAll(Arrays.asList(args).subList(1, args.length));
    System.out.println(s);
}

위 코드로 리플렉션 단점 두가지를 알 수 있다.

  • 일반적으로 생성했으면 컴파일타임에 잡을 수 있는 다수의 예외를 런타임에서야 잡을 수 있다.
  • 일반적으로 생성했으면 생성자 호출 한줄로 끝날 인스턴스 생성을 여러줄 작성해야한다.

 

 

리플렉션이 사용되는 곳

런타임에 존재하지 않을 수도 있는 다르클래스, 메서드, 필드와의 의존성을 관리할 때 적합하다.

주로, 코드 분석 도구, 의존관계 주입 프레임워크에서 많이 사용된다. (Spring)

일반 개발자는 보통 어노테이션과 리플렉션 조합으로 원하는 로직을 만드는 경우에 사용한다.

 

 

결론

리플렉션은 복잡한 특수 시스템을 개발할때 필요한 강력한 기능이지만 단점도 많다.

컴파일타임에는 알 수 없는 클래스를 사용해야한다면 리플렉션을 사용해야할 것이다.

그러나 되도록 객체 생성에만 사용하고 생성한 객체를 이용할때는 적절한 인터페이스나 컴파일타임에 알 수 있는 상위클래스로 형변환하여 사용하라.

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday