꾸준한 스터디
article thumbnail

리플렉션(java.lang.reflect)을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다.

 

  • Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있고
  • 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있다.
  • Constructor, Method, Field 인스턴스를 이용해 각각 연결된 실제 생성자, 메서드, 필드를 조작할 수 있다.
  • 컴파일 당시에 존재하지 않던 클래스도 이용할 수 있다.

 

리플렉션의 단점

  • 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다.
    • 예외 검사도 마찬가지로 프로그램이 리플렉션 기능을 써서 존재하지 않는 혹은 접근할 수 없는 메서드를 호출하려 시도하면 런타임 오류가 발생한다.
  • 리플렉션을 이용하면 코드가 지저분하고 장황해진다.
  • 성능이 떨어진다.
    • 리플렉션을 통한 메서드 호출은 일반 메서드 호출보다 훨씬 느리다. 

 

코드 분석도구나 IOC 컨테이너인 스프링 프레임워크 처럼 리플렉션을 써야하는 복잡한 애플리케이션이 몇 있지만 이런 도구들마저 리플렉션 사용을 점차  줄이고 있다.

 

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

컴파일타임에 이용할 수 없는 클래스를 사용해야만 하는 프로그램은 비록 컴파일타임이라도 적절한 인터페이스나 상위 클래스를 이용할 수는 있을 것이다.

리플렉션은 인스턴스 생성에만 쓰고, 이렇게 만든 인스턴스는 인터페이스나 상위 클래스로 참조해 사용하자.

Set<String> 인터페이스의 인스턴스를 생성하는 프로그램으로 정확한 클래스는 명령줄 첫번째 인수로 확정한다.

두번째 인수들을 Set에 추가한다음 화면에 출력한다.

인텔리제이에서 인수 추가하는 법

HashSet을 지정하면 무작위 순서로 출력

TreeSet을 지정하면 알파벳 순서

 

 

대부분의 경우 리플렉션 기능은 이정도만 사용해도 충분하다.

하지만 이 예는 리플렉션의 단점 두 가지를 보여주는데

  1. 런타임에 총 여섯가지나 되는 예외를 던질 수 있다. 인스턴스를 리플렉션 없이 생성했다면 컴파일타임에 잡아낼 수 있었을 예외들이다.
  2. 클래스 이름만으로 인스턴스를 생성해내기 위해 수줄의 코드를 작성했다. 리플렉션이 아니라면 생성자 호출 한 줄로 끝났을 일이다.
    • 리플렉션 예외 각각 잡는 대신 모든 리플렉션 예외의 상위 클래스인 ReflectiveOperationException을 잡도록하여 코드 길이를 줄일 수 있다.

 

핵심 정리

리플렉션은 복잡한 특수 시스템을 개발할 때 필요한 강력한 기능이지만, 단점도 많다. 컴파일타임에는 알 수 없는 클래스를 사용하는 프로그램을 작성한다면 리플렉션을 사용해야 할 것이다. 단, 되도록 객체 생성에만 사용하고, 생성한 객체를 이용할 때는 적절한 인터페이스나 컴파일타임에 알 수 있는 상위 클래스로 형변환해 사용해야 한다.

profile

꾸준한 스터디

@StudyRecord

포스팅이 유익하셨다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!