Reflection
리플렉션(Reflection)이란 객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법을 말합니다. 약간 어렵죠. 영어 단어로 Reflection은 '거울에 비친 그림자' 또는 '반사' 등의 의미로 사용됩니다. 자세히 관찰하면 자바의 리플렉션은 이 의미를 그대로 따르고 있습니다. 거꾸로라는 의미죠.
▣ 리플렉션(Reflection)이란?
◈ 객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법
일반적으로 여러분들은 클래스를 디자인하고, 클래스의 모든 정보를 담고있는 .class 파일을 만듭니다. 만들어진 클래스를 이용해서 새로운 객체를 선언하고, 그리고 객체의 메모리를 할당하게 됩니다. 그런데 이것을 역으로 생각해 보죠. 만약 객체의 메모리만을 알고 있고, 그리고 이 객체의 형을 모른다고 가정해 보죠. 모든 객체는 Object 클래스를 상속받으니 기본적으로 Object형의 객체로 인식될 수는 있지만, 형을 모른다면 객체 내에 포함되어 있는 메서드를 호출할 수 있을까요? 지금까지 배운 기술로는 불가능합니다. 하지만 리플렉션 기법의 프로그래밍을 이용하면 형을 모르는 상태에서 객체의 메서드를 호출할 수 있습니다.
ⓙ───────────────────────────────────────
/**
클래스의 내의 정보 출력
**/
import java.lang.reflect.*;
import java.util.Vector;
public class ShowClassInfoMain {
public static void main(String [] args) {
Class c = Integer.class;
Class[] iface = c.getInterfaces();
Constructor [] ctor = c.getConstructors();
Method [] m = c.getMethods();
Field[] f = c.getFields();
Class temp = c;
System.out.println("==========start getSuperclass() ============" );
while( (temp=temp.getSuperclass()) != null ){
System.out.println(temp);
}
System.out.println("==========end getSuperclass() ============" );
System.out.println();
System.out.println("==========start getInterfaces() ============" );
for(int i=0; i<iface.length; i++){
System.out.println("interface[" + i + "]:" + iface[i]);
}
System.out.println("==========end getInterfaces() ============" );
System.out.println();
System.out.println("==========start getConstructors() ============" );
for(int i=0; i<ctor.length; i++){
System.out.println("Constructor[" + i + "]:" + ctor[i]);
}
System.out.println("==========end getConstructors() ============" );
System.out.println();
System.out.println("==========start getMethods() ============" );
for(int i=0; i<m.length; i++){
System.out.println("Method[" + i + "]:" + m[i]);
}
System.out.println("==========end getMethods() ============" );
System.out.println();
System.out.println("==========start getFields() ============" );
for(int i=0; i<f.length; i++){
System.out.println("Field[" + i + "]:" + f[i]);
}
System.out.println("==========end getFields() ============");
} //end of main
} //end of ShowClassInfoMain class
C:\tutorial>javac ShowClassInfoMain.java
C:\tutorial>java ShowClassInfoMain
==========start getSuperclass() ============
class java.lang.Number
class java.lang.Object
==========end getSuperclass() ============
==========start getInterfaces() ============
interface[0]:interface java.lang.Comparable
==========end getInterfaces() ============
==========start getConstructors() ============
Constructor[0]:public java.lang.Integer(java.lang.String) throws java.lang.NumberFormatException
Constructor[1]:public java.lang.Integer(int)
==========end getConstructors() ============
==========start getMethods() ============
Method[0]:public int java.lang.Integer.hashCode()
Method[1]:public static int java.lang.Integer.reverseBytes(int)
Method[2]:public boolean java.lang.Integer.equals(java.lang.Object)
Method[3]:public int java.lang.Integer.compareTo(java.lang.Object)
Method[4]:public int java.lang.Integer.compareTo(java.lang.Integer)
Method[5]:public static java.lang.String java.lang.Integer.toString(int,int)
Method[6]:public static java.lang.String java.lang.Integer.toString(int)
Method[7]:public java.lang.String java.lang.Integer.toString()
Method[8]:public static java.lang.String java.lang.Integer.toHexString(int)
Method[9]:public static java.lang.Integer java.lang.Integer.decode(java.lang.String) throws java.lang.NumberFormatException
Method[10]:public static java.lang.Integer java.lang.Integer.valueOf(java.lang.String,int) throws java.lang.NumberFormat
Exception
Method[11]:public static java.lang.Integer java.lang.Integer.valueOf(int)
Method[12]:public static java.lang.Integer java.lang.Integer.valueOf(java.lang.String) throws java.lang.NumberFormatException
Method[13]:public static int java.lang.Integer.reverse(int)
Method[14]:public byte java.lang.Integer.byteValue()
Method[15]:public double java.lang.Integer.doubleValue()
Method[16]:public float java.lang.Integer.floatValue()
Method[17]:public int java.lang.Integer.intValue()
Method[18]:public long java.lang.Integer.longValue()
Method[19]:public short java.lang.Integer.shortValue()
Method[20]:public static int java.lang.Integer.parseInt(java.lang.String) throws java.lang.NumberFormatException
Method[21]:public static int java.lang.Integer.parseInt(java.lang.String,int) throws java.lang.NumberFormatException
Method[22]:public static int java.lang.Integer.bitCount(int)
Method[23]:public static java.lang.Integer java.lang.Integer.getInteger(java.lang.String,java.lang.Integer)
Method[24]:public static java.lang.Integer java.lang.Integer.getInteger(java.lang.String)
Method[25]:public static java.lang.Integer java.lang.Integer.getInteger(java.lang.String,int)
Method[26]:public static int java.lang.Integer.highestOneBit(int)
Method[27]:public static int java.lang.Integer.lowestOneBit(int)
Method[28]:public static int java.lang.Integer.numberOfLeadingZeros(int)
Method[29]:public static int java.lang.Integer.numberOfTrailingZeros(int)
Method[30]:public static int java.lang.Integer.rotateLeft(int,int)
Method[31]:public static int java.lang.Integer.rotateRight(int,int)
Method[32]:public static int java.lang.Integer.signum(int)
Method[33]:public static java.lang.String java.lang.Integer.toBinaryString(int)
Method[34]:public static java.lang.String java.lang.Integer.toOctalString(int)
Method[35]:public final void java.lang.Object.wait() throws java.lang.InterruptedException
Method[36]:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
Method[37]:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
Method[38]:public final native java.lang.Class java.lang.Object.getClass()
Method[39]:public final native void java.lang.Object.notify()
Method[40]:public final native void java.lang.Object.notifyAll()
==========end getMethods() ============
==========start getFields() ============
Field[0]:public static final int java.lang.Integer.MIN_VALUE
Field[1]:public static final int java.lang.Integer.MAX_VALUE
Field[2]:public static final java.lang.Class java.lang.Integer.TYPE
Field[3]:public static final int java.lang.Integer.SIZE
==========end getFields() ============
***/
───────────────────────────────────────ⓑ
▣ 정적 바인딩
가상머신이 바이트 코드로 된 .class 파일을 로딩한 후에 객체를 생성할 수 있듯이, 프로그래머가 .class 파일을 직접 로딩한 후 Class 클래스를 이용해서 객체를 생성할 수도 있습니다. 일반적인 방법으로 객체를 생성하면 가상머신이 그 다음 작업을 해주는 것입니다.
◈ 컴파일할 때 해당 .class 파일이 필요하다면, 해당 클래스를 정적 바인딩으로 사용하는 것이다.
▣ 동적 바인딩으로 클래스 로딩
클래스의 동적 바인딩은 컴파일할 때 해당 클래스가 없어도 됩니다. 말그대로 프로그램이 실행되고 난 뒤에 동적으로 위치 를 명시하고, 해당 클래스(.class)를 로딩해서 객체를 만든다든지 메서드를 호출할 수 있습니다. 일반적으로 말하는 리플렉션 의 기법은 정적 바인딩 클래스가 아니라 동적 바인딩 클래스를 의미합니다. 동적 바인딩의 기법으로 클래스를 로딩하는 방법은 다음 과 같습니다.
◈ Class c = Class.forName("클래스이름");
클래스의 이름 자체를 컴파일 타임에 사용할 수 없기 때문에 문자열 형태로 클래스의 이름을 사용합니다. 그리고 Class.forName("클래스이름")이 호출되는 바로 그 순간에 클래스를 로딩하겠다는 의미가 됩니다.
◈ 클래스의 이름을 문자열로 사용하는 이유는 해당 클래스가 컴파일할 때 없기 때문입니다.
◈ 동적 바인딩을 활용하면, 웹서버에(URLClassLoader이용) 있는 Class를 가져올 수 도 있다.
▣ 리플렉션 기법들
◈ 생성자에 매개변수가 없는 객체 생성하기
◈ 생성자에 매개변수가 있는 객체 생성하기
◈ 매개변수가 없는 메서드 호출하기
◈ 매개변수가 있는 메서드 호출하기
◈ 특정객체에 멤버 필드 값 셋팅하기
◈ 특정객체에 멤버 필드 값 얻어내기 .
출처 : http://blog.naver.com/PostView.nhn?blogId=ypark197&logNo=90093550962&redirect=Dlog&widgetTypeCall=true
'프로그래밍(~2017) > 자바' 카테고리의 다른 글
[자바]사용자 기본 홈 디렉토리 경로 찾기 (0) | 2011.11.10 |
---|---|
inner 내부 클래스가 존재하는 클래스에서 외부클래스를 나타내는 this와 내부클래스를 나타내는 this- 클래스.this (0) | 2011.10.14 |
[Java] 리플렉션에 대한 재고 (0) | 2011.08.18 |
자바 제네릭 관련 정리 (0) | 2011.08.18 |
[자바] HMAC-SHA1 + Base64 (0) | 2011.08.09 |