2008년 12월 17일
리플렉션(Reflection)
프로그래밍 언어는 컴퓨터의 자원을 이름(name)과 식별자(identifier)로 추상화한 개념을 사용합니다. 실제로 이름과 식별자가 컴퓨터의 자원으로 구체화되는 과정을 바인딩이라 부릅니다. 구체화하는 과정에서 바인딩하는 시점은 언어 정의 시간, 언어 구현 시간, 번역 시간, 실행 시간 네가지로 구분됩니다ㅏ. 여기서 언어 정의 시간, 언어 구현 시간과 번역 시간에 구체화되면 이른 바인딩(early binding) 이라고 부르고, 실행 시간에 구체화되면 늦은 바인딩(late binding)이라고 부릅니다. 또 번역 시간을 정적 바인딩(static binding), 실행 시간을 동적 바인딩(dynamic binding)이라고 부르는데 자바에서는 늦은 바이딩(late binding)을 리플렉션이라고 부립니다.

자바는 리플레션 API를 이용하여 스스로를 관찰하고 관리할 수 있습니다. 이것은 Class 클래스와 java.lang.reflect 패키지의 클래스들로 구성되는데, 여기서 제공하는 Method, Constructor, Field 객체들로 클래스의 멤버들을 표현할 수 있습니다. 

  /**
   * Employee 클래스의 간단한 정보 출력 ..
   
   @throws ClassNotFoundException
   */

  static void classInfo() throws ClassNotFoundException
  {
    Employee employee = new Employee();
    /*
     * Class 객체를 얻는 3가지 방법
     */
//  Class klass = employee.getClass();
//  Class klass = Employee.class;
    Class klass = Class.forName("com.greenfrog.reflect.Employee");

    System.out.println("Class name : " + klass.getName());
    System.out.println("Class super class : " + klass.getSuperclass());

    int mods = klass.getModifiers();

    System.out.println("Class is public : " + Modifier.isPublic(mods));
    System.out.println("Class is final : " + Modifier.isFinal(mods));
    System.out.println("Class is abstract : " + Modifier.isAbstract(mods));
  }

  /**
   * Class 객체를 이용해서 해당 클래스의 인스턴스 생성하기
   
   @throws InstantiationException - 추상클래스이거나 인터페이스일 때 객체 생성을 할 수 없다 .. 
   @throws IllegalAccessException - 생성 된 클래스에서 정의되지 않은 멤버에 접근 할 수 없다 .. 
   @throws ClassNotFoundException
   */

  static void newInstance(
            throws InstantiationException, IllegalAccessException, ClassNotFoundException
  {
    Class klass = Class.forName("com.greenfrog.reflect.Employee");
    Object obj = klass.newInstance();

    System.out.println("Just made : " + obj);  
  }

  /**
   * 객체 생성 시 인자 있는 생성자 호출하기 ..
   *
   @throws ClassNotFoundException
   @throws NoSuchMethodException - Thrown when a particular method cannot be found. 
   @throws SecurityException - Thrown by the security manager to indicate a security violation.
   @throws InvocationTargetException 
   @throws IllegalAccessException 
   @throws InstantiationException 
   @throws IllegalArgumentException -Thrown to indicate that a method has been passed an illegal or inappropriate argument. 
   */
  static void newInstanceUsingConstructor() throws ClassNotFoundException, SecurityException, 
          NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException
  {
    Class klass = Class.forName("com.greenfrog.reflect.Employee");

    
Class[] paramTypes = String.class, String.class, Integer.TYPE };

    Constructor cons = klass.getConstructor(paramTypes);

    System.out.println("Found the constructor : " + cons);

    Object[] args = {"Fred""Fintstone"new Integer(90000) };
    Object obj = cons.newInstance(args);

    System.out.println("New object : " + obj);
  }

  
  /**
   * Function 클래스의 이름(문자열)을 이용해서 객체를 생성하고 메소드의 이름(문자열)을 이용해서 메소드 실행시키기 ..
   
   @throws SecurityException
   @throws NoSuchMethodException
   @throws IllegalArgumentException
   @throws IllegalAccessException
   @throws InvocationTargetException
   @throws ClassNotFoundException
   @throws InstantiationException
   */

  static void executeFuncInTestClass() 
            
throws SecurityException, NoSuchMethodException, IllegalArgumentException,
      IllegalAccessException, InvocationTargetException, ClassNotFoundException, InstantiationException 
  {
    Class klass = Class.forName("com.greenfrog.reflect.Function");
    Object obj = klass.newInstance();

//     방법 1.
    Method method = klass.getMethod("func"new Class[] { Integer.TYPE });
    method.invoke(obj, new Object[] { new Integer(37) });

//    방법 2.
//    Function fuction = (Function) obj;
//    fuction.func(100);
  }

  

  /**
   * Function 클래스의 이름(문자열)을 이용해서 객체를 생성하고 메소드의 이름(문자열)을 이용해서 배열을 인자로하는 메소드 실행시키기 
   
   @throws SecurityException
   @throws NoSuchMethodException
   @throws IllegalArgumentException
   @throws IllegalAccessException
   @throws InvocationTargetException
   @throws ClassNotFoundException
   @throws InstantiationException
   */

  static void executeFuncArrInTestClass() 
            
throws SecurityException, NoSuchMethodException, IllegalArgumentException,
      IllegalAccessException, InvocationTargetException, ClassNotFoundException, InstantiationException 
  {
    Class klass = Class.forName("com.greenfrog.reflect.Test");
    Object obj = klass.newInstance();

    Method method = klass.getMethod("func"new Class[] { int[].class });

    int[] arr = new int[5];
    for(int i=0; i<arr.length; i++)
      arr[i= i;

    method.invoke(obj, new Object[] { arr });
  }


* 참고 사이트 및 문헌

Java 리플렉션에 대한 재고(reflection)(1)
함께하는 세상

예제로 배우는 자바 프로그래밍 (한빛미디어) p.339 ~ 345
Java Tip & Thech (영진닷컴) p.246 ~ 257

* 샘플 프로젝트

Reflection.zip
by greenfrog | 2008/12/17 20:13 | JAVA | 트랙백 | 덧글(3)
트랙백 주소 : http://greenfrog7.egloos.com/tb/1250419
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 빛이드는창 at 2008/12/18 08:52
좋은 정보 잘 보고 갑니다.
Commented by greenfrog at 2008/12/18 09:31
도움이 되셨다면 저도 보람되네요 ^^
Commented by 인철 at 2010/06/25 22:25
제 블로그에 내용 좀 ^^;;

:         :

:

비공개 덧글



<< 이전 페이지 | 다음 페이지 >>