자바 reflection




리플렉션(reflection) 자바 프로그래밍 언어의 기능 하나다. 리플렉션을 사용하면 자바 프로그램을 실행해서 해당 프로그램을 조사하거나 스스로를 살펴볼(introspect) 있다. 또한 프로그램의 내부 프로퍼티를 조작할 수도 있다. 예를 들어 리플렉션을 사용하면 자바 클래스에서 해당 클래스의 멤버의 이름을 모두 획득해서 표시할 있다.

자바 클래스에서 스스로를 조사하고 조작하는 이러한 기능이 그리 대단해 보이지 않을 수도 있다. 하지만 이러한 기능을 지원하지 않는 프로그래밍 언어도 있다. 예를 들어 파스칼, C, C++ 프로그램에서는 해당 프로그램 안에 정의된 함수에 대한 정보를 얻을 있는 방법이 없다.

실제로 자바 (JavaBeans)에서 리플렉션을 적용했다. 자바 빈을 사용하면 소프트웨어 컴포넌트를 빌더 툴을 사용해서 시각적으로 조작할 있다. 이러한 빌더 툴은  자바 컴포넌트(클래스) 동적으로  로드될 , 리플렉션을 사용해서 해당 컴포넌트의 프로퍼티를 획득한다.

간단한 예제
리플렉션이 어떻게 동작하는지 아래의 간단한 예를 통해 살펴보자:

   import java.lang.reflect.*;
 
   public class DumpMethods {
      public static void main(String args[])
      {
         try {
            Class c = Class.forName(args[0]);
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++)
            System.out.println(m[i].toString());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


아래와 같이 실행해 보면

java DumpMethods java.util.Stack


결과는 다음과 같다:

public java.lang.Object java.util.Stack.push(java.lang.Object)
public synchronized java.lang.Object java.util.Stack.pop()
public synchronized java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized int java.util.Stack.search(java.lang.Object)


보다시피 java.util.Stack 클래스의 메서드 명이 출력된다. 메서드의 파라미터와 리턴 타입 또한 패키지 명을 포함해서 출력된다.

프로그램은 Class.forName 사용해서 기술된 클래스를 로드한 getDeclaredMethods를 호출해서 해당 클래스에 정의된 메서드 목록을 얻는다. java.lang.reflect.Method는 클래스에서 단일 메서드를 나타내는 클래스다.


리플렉션 사용을 위한 설정
Method
같이 리플렉션을 위한 클래스는 java.lang.reflect 패키지에서 찾을 있다. 패키지에 있는 클래스를 사용하려면 단계를 거쳐야만 한다. 단계로 조작하려는 클래스에 해당하는 java.lang.Class 객체를 얻어야 한다java.lang.Class는 실행 중인 자바 프로그램에서 클래스 또는 인터페이스를 나타내기 위해 사용한다.

Class
객체를 얻을 있는 가지 방법은 다음과 같다:

Class c = Class.forName("java.lang.String");


같이 사용하면 String 대한 Class 객체를 얻을 있다. 또는 다음과 같이 사용할 수도 있다:

Class c = int.class;   // 또는
Class c = Integer.TYPE; 


같이 사용하면 기본형에 대한 Claass 정보를 얻을 있다. 번째 방법의 경우, 기본현에 대한 래퍼 클래스(Integer 같이) 미리 정의된 TYPE 필드에 접근한다.

번째 단계는 getDeclaredMethods와 같은 메서드를 호출하는 작업으로, getDeclaredMethods를 호출하면 해당 클래스에 선언된 메서드의 목록을 모두 얻을 수 있다.

이러한 정보를 모두 얻고 나면, 번째 단계로 리플렉션 API 사용해서 해당 정보를 조작할 있다. 예를 들어 아래와 같은 일련의 문장을 실행하면,

Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());


String
선언된 번째 메서드를 텍스트 형식으로 표시하게 된다.

이후에 다룰 예제에서는 지금 설명한 단계를 결합해서 사용한다. 이를 통해 특정한 목적에 맞게 리플렉션을 활용하는 방식을 효과적으로 처리하는 예제를 한꺼번에 보여주고자 한다.

결론
자바 리플렉션을 사용하면 클래스와 데이터 구조에 대한 정보를 이름을 기반으로 동적으로 얻을 있다는 점에서 매우 유용하다. 뿐만 아니라 리플렉션을 사용하면 자바 프로그램을 실행하는 동안에 해당 클래스를 조작할 있다. 기능은 믿을 없을 정도로 강력하며, C, C++, 포트란, 파스칼과 같은 자바 이외의 언어에서는 리플렉션에 해당하는 기능이 전혀 없다.

'Develop > Java' 카테고리의 다른 글

String, StringBuffer, StringBuilder  (0) 2016.12.01
Quick sort  (0) 2016.11.21
문자열 "ABCDEFG"를 역순으로 출력  (0) 2016.11.17
JAVA의 접근제한자  (0) 2016.11.15
오버로딩 vs 오버라이딩  (0) 2016.11.14

+ Recent posts