Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

미래학자

리플렉션 개념 익히기 본문

JAVA

리플렉션 개념 익히기

미래학자 2017. 1. 3. 16:58

일반적으로 클래스를 통해 객체를 생성했다. 우리는 코딩할 때 클래스에 명시된 필드와 메소드를 알고 있기 때문에 지금까지 클래스의 메소드 또는 필드를 이용하는데 아무런 불편함이 없었다. 이전 시간에 객체를 생성할 때 클래스의 메타데이터를 먼저 읽는 것을 이해했다. 이 메타데이터에는 클래스의 필드, 메소드 등의 정보를 담고 있다. 이런 메타데이터를 통해 해당 클래스의 객체를 생성할 수 있다. 

 이렇게 한 번 설명해보겠다. 오류가 있을 수 있으니 잘못된점이 있다면 지적해주시면 정말 감사할 것이다.

 

타조, 앵무새, 비행기, 사자, 뻐꾸기, 말 이렇게 6가지 클래스가 있다고 하자. 이 중 fly() 함수가 있는 클래스는 타조, 앵무새, 비행기, 뻐꾸기다. 

새(abstract class) - 앵무새, 타조, 뻐꾸기    -> 앵무새, 타조, 뻐꾸기는 모두 새를 상속받았다. 새는 fly()라는 메소드가를 갖는다. 

비행기는 새를 상속받지 않았지만 fly()라는 메소드가 있다.

6개의 객체 중 아무나 뽑아 fly() 메소드를 실행하려 한다. 기존 생각은 새를 상속 받은 클래스면 fly()를 호출하도록 하고, 또 instanceof()로 비행기 객체면 fly()를 호출하면 될 것이다. 이렇게 해도 문제가 없어보이지만, 이 숫자가 매우 많다면 어떻게 될까??


리플렉션을 이용하면 fly()메소드가 있는지 확인하여 메소드를 호출할지 안할지 결정할 수 있다.


  • 리플렉션 기법 1 : 런타임 중에 객체를 이용해서 객체의 정보를 조사할 수 있다.
  • 리플렉션 기법 2 : 런타임 중에 프로그램의 상태나 기능을 동적으로 조작할 수 있다.
  • 리플레션 기법 3 : 동적이며 유연한 프로그래밍이 가능하기 때문에 프레임워크에서 주로 사용된다.
리플렉션을 통해서 얻을 수 있는 정보

  • 클래스 이름
  • 클래스의 제어자(예: public, private, static)
  • 패키지의 정보(예: java.lang.System)
  • 클래스의 부모 클래스(Class 클래스형을 갖는 객체를 받을 수 있다.)
  • 클래스의 생성자(Constructor 클래스형을 갖는 객체를 받을 수 있다.)
  • 클래스의 메소드(Method 클래스형을 갖는 객체를 받을 수 있다.)
  • 클래스의 변수(Field 클래스형을 갖는 객체를 받을 수 있다.)
  • 클래스의 Annotation(Annotation은 주석의 일종으로 Annotation 클래스형을 갖는 객체를 받을 수 있다.)
아래의 코드는 뒤에 사용될 리플렉션 예제를 위한 모델 객체다.



리플렉션을 하기 위해서는 클래스 정보를 얻을 수 있는 java.lang.Class 클래스가 필요하다. 우선 Class 객체를 생성하는 방법에 대해 살펴보자.



실제로 Class 객체를 생성해보면,



위 코드 결과는 아래와 같다. 해시 코드는 매번 실행할 때마다 다를 수 있으나, 그 값은 항상 같다. HashCode가 같으면 같은 객체다.



HashCode = class1 : 1639705018
HashCode = class2 : 1639705018
HashCode = class3 : 1639705018
HashCode = null : 0



위 코드를 이용하여 간단하게 WorkerVlaue 클래스의 생성자, 메소드, 필드를 확인할 수 있다. 실행 결과는 아래와 같다.

-Constructor----------------------------
public WorkerValue(java.lang.String,int)
public WorkerValue()
-Method-------------------------------
public static void WorkerValue.main(java.lang.String[])
public java.lang.String WorkerValue.toString()
public java.lang.String WorkerValue.getName()
public void WorkerValue.setName(java.lang.String)
public void WorkerValue.test()
public int WorkerValue.getPosition()
public void WorkerValue.setPosition(int)
-Field----------------------------
public static int WorkerValue.POSITION_MANAGER
public static int WorkerValue.POSITION_ASSISTANT
public static int WorkerValue.POSITION_EMPLOYEE

Class 클래스에는 Annotion이나 제네릭과 같은 정보를 확인할 수 있는 메소드들도 있다. 리플렉션은 단순히 해당 클래스에 어떤 메소드, 필드가 있냐에 그치지 않고 반환받은 Method, Field 또는 Constructor 객체를 사용하여 동적으로 실행ㅎ는 프로그래밍을 할 수 있다. 


다음 포스팅에서는 java.lang.reflect 패키지를 살펴볼 것이다. 이미 이번 포스팅에서 java.lang.reflection.Method, Field, Constructor를 Import 했다. 다음 장에서는 더욱 자세히 다루도록 하고 동적으로 프로그래밍하는 방법을 공부할 것이다.


Comments