[Effective Java] 리플렉션보다는 인터페이스를 사용하라

들어가며

리플렉션을 사용하면 프로그램에서 임의의 클래스에 접근이 가능하다. Class 객체를 주어지면 생성자 메소드 필드 인스턴스를 가져올 수 있고 인스턴스에 해당하는 이름 타입 시그니처 등을 가져올 수 있다. 또한 그 메소드나 인스턴스를 호출이나 접근할 수 있다. 리플렉션을 이용하면 컴파일 당시에 존재하지 않던 클래스도 이용할 수 있다. 하지만 리플렉션도 단점은 있다.

  1. 컴파일타임 타입 검사가 주는 이점을 누릴 수 없다.
    • 프로그램이 리플렉션을 써서 존재하지 않거나 접근할 수 없는 메소드를 호출하려고 시도하면 런타임 오류가 발생한다.
  2. 리플렉션을 이용하면 코드가 지저분해지고 장황해진다.
  3. 성능이 떨어진다.
    • 동적으로 코드를 해석하는 동작이 들어가기 때문에 JVM에서 제공하는 최적화를 제공받을 수 없다.

코드 분석 도구나 DI 프레임워크에서처럼 리플렉션을 써야하는 어플리케이션이 있다. 스프링의 ORM 기술인 하이버네이트와 같은 것들이 이에 해당한다. 리플렉션은 아주 제한된 형태로만 사용해야 그 단점을 피하고 이점만 취할 수 있다. 컴파일 타임에 이용할 수 없는 클래스를 사용해야만 하는 프로그램은 비록 컴파일 타임이더라도 적절한 인터페이스나 상위 클래스를 사용할 수 있을것이다. 이런 경우에는 인스턴스 생성에만 리플렉션을 사용하고 이후에는 인스턴스의 인터페이스나 상위 클래스로 참조하면 된다.

리플렉션으로 코드를 작성할때는 단점이 많다. 런타임에 많은 수의 예외를 던진다. 대부분 리플렉션 없이 인스턴스를 생성했다면 컴파일타임에 잡을 수 있는 오류들이다. 두번째로는 코드가 장확하게 길어지며 복잡해진다.

드물지만 리플렉션은 런타임에 존재하지 않을 수도 있는 다른 클래스, 메소드, 필드와의 의존성을 관리할 때 적합하다. 이 방법은 버전이 여러 개 존재하는 외부 패키지를 다룰 때 기동을 위한 최소 환경 즉, 가장 오래된 버전만 지원하도록 컴파일한 후 이후 버전의 클래스와 메소드 등은 리플렉션으로 접근하는 방식이다.

Author: Song Hayoung
Link: https://songhayoung.github.io/2020/08/21/Languages/Effective%20JAVA/item65/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.