자바 리플렉션(Reflection)이란 컴파일된 자바 코드에서 역으로 클래스를 불러서 메소드(Method) 및 변수(Field)를 구해오는 방법으로 클래스를 동적 로딩하여 사용할때 많이 사용되고 디컴파일할때에도 자주 사용되는 기법이다.
1. 리플렉션(Reflection) 기본
예를들어 아래와 같이 Class가 있다고 하면 생성자(Constructor)도 있을것이고, 필드(Field) 및 메쏘드(Method)도 있을것이다.
vi MyClass.java |
- public class MyClass{
- private static String myName = null;
- public String pubString = null;
- private void hiddenMethod()
- {
- System.out.print("hello private");
- }
- public MyClass()
- {
- }
- public int mySum(int a,int b)
- {
- return a+b;
- }
- public MyClass (String myname){
- this.myName = myname;
- }
- public String getMyName()
- {
- return myName;
- }
- public void setMyName(String myName)
- {
- this.myName = myName;
- }
- } // javac MyClass.java
그렇다면 이를 사용하는 소스코드에서는 아래와같은 형식으로 사용된다.
vi MyJava.java |
- import java.io.*;
- public class MyJava
- {
- public static void main(String args[])
- {
- MyClass myClass = new MyClass("kaspyx");
- String myName = myClass.getMyName();
- System.out.println("My name is "+myName);
- }
- } // javac MyJava.java
다시한번 설명을 하자면
MyClass myClass = new MyClass("kaspyx")
String myName = myClass.getMyName();
이런식으로 사용되는데, 이를 Reflection 으로 풀어보면 아래처럼 된다.
vi MyReflector.java |
- import java.io.*;
- import java.lang.reflect.*;
- public class MyReflector
- {
- public static void main(String args[])
- {
- try{
- Class myClass = Class.forName("MyClass");
- Constructor myConstuctor = myClass.getConstructor( new Class[] {String.class });
- Object myObj = myConstuctor.newInstance("kaspyx");
- Method method = myClass.getMethod("getMyName");
- String myName = (String)method.invoke(myObj);
- System.out.println("Myname is "+ myName);
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- } // javac MyReflector.java
vi MyReflector.java |
- import java.io.*;
- import java.lang.reflect.*;
- public class MyReflector
- {
- public static void main(String args[])
- {
- try{
- Class myClass = Class.forName("MyClass");
- Constructor myConstuctor = myClass.getConstructor( new Class[] {String.class });
- Object myObj = myConstuctor.newInstance("kaspyx");
- Method method = myClass.getMethod("getMyName");
- String myName = (String)method.invoke(myObj);
- System.out.println("Myname is "+ myName);
- Class[] methodParamClass = new Class[] { String.class };
- Object[] methodParamObject = new Object[] {"Kyungsu Kim"};
- Method method2 = myClass.getMethod("setMyName",methodParamClass);
- method2.invoke(myObj, methodParamObject);
- myName = (String)method.invoke(myObj);
- System.out.println("Changed myname is "+ myName);
- Class[] intParamClass = new Class[] {int.class, int.class};
- Object[] intParamObject = new Object[] {1, 2};
- Method method3 = myClass.getMethod("mySum",intParamClass);
- int sum = (int)method3.invoke(myObj,intParamObject);
- System.out.println("Sum is " + sum);
- Field field = myClass.getDeclaredField("myName");
- field.setAccessible(true);
- field.set(null,"No kaspy~!");
- String myName2 = (String)field.get(myObj);
- System.out.println("Myname2 is "+ myName2);
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- } // javac MyReflector.java
4. 그외 리플렉션(Reflection) 함수들
Java 에서는 위에서 설명한 함수들을 제공해주고있다.
getMethods() , getFields() 등등을 사용하면 함수이나 변수이름을 몰라도 불러올수있으며, 이함수는 public으로 선언한 메소드(함수)나 필드(변수)를 가져온다. getMethod()는 문자열을 가지고 단일 함수를 찾아주지만 getDeclaredMethods()는 private 포함 클래스 내부에서 선언한 함수만 찾아준다.
비슷한 기능이지만 조금씩 다르니 레퍼런스를 잘 참고해서 용도에 맞게 써줘야할것이다.
코딩을 통해 확인해보자.
vi MyReflector2.java |
- import java.io.*;
- import java.lang.reflect.*;
- public class MyReflector2
- {
- public static void main(String args[])
- {
- try{
- Class myClass = Class.forName("MyClass");
- Method methods[] = myClass.getDeclaredMethods();
- System.out.println("1.DeclaredMethods() ================");
- for (Method method: methods)
- {
- System.out.println("Found method name: " + method);
- }
- Method methods2[] = myClass.getMethods();
- System.out.println("2.getMethods() =====================");
- for (Method method: methods2)
- {
- System.out.println("Found method name: " + method);
- }
- Field fields[] = myClass.getFields();
- System.out.println("3.getFields=========================");
- for (Field field: fields)
- {
- System.out.println("Found field name: " + field);
- }
- Constructor myConstuctor = myClass.getConstructor( new Class[] {String.class });
- Method hiddenMethod = myClass.getDeclaredMethod("hiddenMethod");
- System.out.println("5.=================================");
- System.out.println("Hidden method name is "+hiddenMethod.getName());
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- } // javac MyReflector2.java
* 실행 결과화면
5. 참고자료
https://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html
'IT > Java' 카테고리의 다른 글
자바(Java)로 구현한 RSA 암호학 알고리즘 예제 (0) | 2015.11.12 |
---|---|
Java로 달력(Calendar) 구현하기 (0) | 2015.05.18 |