JAVA/Effective Java

규칙 53 - 리플렉션 대신 인터페이스를 이용하라

반응형

자바에서 제공하는 리필렉션 기능을 이용하면 메모리에 로드된 클래스 정보를 바탕으로 필드 정보를 가져오거나, 메서드를 실행시키고 객체를 만드는 등 다양하게 조작을 할 수 있다.

하지만 여기서 이런 리플렉션 기능에는 단점이 존재한다.

1. 컴파일 시점에 자료형을 검사하면서 얻을 수 있는 예외 처리에 대한 이점을 포기해야한다. 또한 접근할 수 없는 메서드를 호출하게 되는 경우에는 오류를 발생시킬 수 있다.
2. 리플렉션 기능을 이용하면 코드가 가독성이 떨어진다.
3. 리플렉션을 통한 메서드 호출은 일반적인 방식 보다 속도가 2 ~ 50배 정도 늦어진다.

사실 리플렉션은 컴포넌트 기반 응용 프로그램 저작 도구를 위해 개발 되었기 때문에, 일반적인 프로그램은 프로그램 실행 중에 리플렉션을 통해 객체를 이용하려 하면 안된다.

그래서 제한적으로 리플렉션을 사용해야 오버헤드를 피하면서 다양한 장점을 누릴 수 있다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
        Class<?> ci = null;
        try {
            ci = Class.forName(args[0]);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        Set<String> s = null;
        try {
            s = (Set<String>) ci.newInstance();
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }
cs




위의 코드를 보면 Set<String> 객체를 생성할 때 TreeSet 또는 HashSet을 유동적으로 결정하여 만들 수 있다. 그런 부분에서는 굉장한 장점이라고 생각할 수 있다.

하지만

위의 코드의 경우 잘못된 argument값이 들어오게 될 경우 exception이 발생된다. 또한 그냥 객체를 만들면 한줄이면 되는 코드가 되게 길게 늘어지게 되어 가독성이 떨어진다.

장점보다 단점이 많은 리플렉션 기능을 사용을 자제하는 것이 좋다.
만약 컴파일 시점이 아닌 실행시점에 결정이되는 클래스를 만들어야 하는 경우에는, 리플렉션을 사용하되 가능하면 객체를 만들 때만 사요하고, 객체를 참조할 때는 컴파일 시에 알고 있는 인터페이스나 상위 클래스를 이용하는 것이 좋다.(위에서 Set으로 객체를 참조한 것과 같이)



출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙53 인용.

반응형