시소당
자북(http://schatzi.konkuk.ac.kr/)에서 Class 클래스에 대한 얘기에서부터 리플렉션의 구현 부분을 봤습니다.
비교적 알기 쉽게 되어있었는데요.
예제코드에 이해가 가지 않는 구문이 있어서요.
아래는 이해가 '가는' 코드입니다. 리플렉션의 구현에서 '생성자 매개변수가 없는 객체 생성하기' 인데요.
------
import java.util.Vector;
public class NewObjectTest{
public static void main(String[] arg)
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
Object object = null;
Class c = Class.forName("java.util.Vector");
object = c.newInstance();
if(object instanceof Vector){
System.out.println("Vector형이 맞습니다.");
} else {
System.out.println("Vector형이 아닙니다.");
}
}
}
----
위의 예제는 이해가 갑니다. 일단 c라는 객체는 Vector 클래스자체를 의미하니까 그걸 클래스 로더에 로딩하고 그걸 기반으로 newInstance() 메소드를 사용해서 객체를 만드는 것 같군요.
문제는 위의 예제와는 다른 '생성자 매개변수가 있는 객체 생성하기 입니다.
------------
import java.lang.reflect.*;
public class NewObjectTest2{
public static void main(String[] arg)
throws ClassNotFoundException, InstantiationException, IllegalAccessException
,NoSuchMethodException, InvocationTargetException
{
Class c = String.class;
Class[] argType = new Class[]{String.class};
Constructor con = c.getConstructor(argType);
Object[] initArg = new Object[]{"Hello World"};
Object obj = con.newInstance(initArg);
if(obj instanceof String){
System.out.println("String형이 맞습니다.:" + obj);
} else {
System.out.println("Vector형이 아닙니다.");
}
}
}
---------
여기서 익숙하지 않은 구문이 나왔는데요.
Class[] argType = new Class[]{String.class};
이겁니다. 이게 대체 뭘 의미하는지 잘 모르겠네요. Class 클래스형 객체 argType을 배열의 형태로 만들었는데 첨자를 주지 않은걸 볼 수 있습니다.
여기서 어떻게해서 첨자를 주지 않아도 되는지 모르겠네요. argType 객체배열의 length를 출력해보니 1이 나오더군요. 1이 나오는건 배열이 생성되긴 했다는 얘긴데...
이것때문에 여러 가능성을 생각해봤는데요. 한가지는 중괄호 안에 있는 String.class가 생성자 매개변수가 아닌가 했습니다.
시험삼아서 아래와 같은 문장을 넣고 컴파일을 해보았습니다.
String[] s = new String[]{"시험"};
그랬더니 컴파일도 잘되고 s의 length도 1이 나오는군요. s[0]의 내용도 "시험"이라는 문자열 그대로 출력됩니다.
근데 문제는
String[] s = new String[5]{"시험"};
이런식으로 첨자를 주게되면 세미콜론이 빠졌다면서 컴파일 에러가 나네요. 그렇다면 단순한 생성자 매개변수는 아닌것 같은데....
Class 클래스 객체를 얻는 방법은
Class c = String.class; 이거나
Class c = Class.forName(“java.lang.String”);
이런 식으로 한다고 알고 있는데요. 어떻게 위에 말한 저런 문장이 나오는지 궁금합니다.
질문자가 선택한 답변 -->
re: 자바 Reflection의 문법에서 질문
이의제기 | 신고-->
sungilk (2005-07-15 13:22 작성, 2005-07-15 13:22 수정)
이의제기 | 신고
질문자 평
아 배열을 잊고 있었네요. 배열 특유의 제한성때문에 벡터를 더 많이 사용해서 배열초기화에 대한 부분을 까먹었습니다=ㅂ=
위의 질문은 Reflection과는 상관이 없구요
자바의 배열 초기화 방법과 관련이 있습니다.
위의 경우는 배열의 선언과 동시에 초기화를 하는 방법이구요
아래 예를 테스트해보시기 바랍니다.
class ArrayTest
{
public static void main(String[] args)
{
// arr1과 arr2는 선언과 초기화를 동시에 하는 경우 이구요
//arr3은 선언과 초기화를 따로하는 경우 입니다.
// 질문하신 경우는 arr1의 경우에 해당 합니다.
int[] arr1 = new int[]{1, 2, 3, 4};
int[] arr2 = {5, 6, 7, 8};
int[] arr3 = new int[3];
arr3[0] = 9;
arr3[1] = 10;
arr3[2] = 11;
System.out.println("### array 1 ###");
for(int i=0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
System.out.println("\n### array 2 ###");
for(int i=0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
System.out.println("\n### array 3 ###");
for(int i=0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
}
}
도움이 되셨길...
질문자가 선택한 답변 -->
re: 자바 Reflection의 문법에서 질문
이의제기 | 신고-->
cuteshim (2005-07-15 15:16 작성)
이의제기 | 신고
질문자 평
리플렉션에 대해 도움이 많이 되었습니다. 답변자님 덕분에 좀더 편하게
위엣분이 리플렉션에 대해 정확하게 이해를 하지 못한것 같네요
위엣분도 같이 봤으면 좋겠습니다.
핵심 코드만 나열 하겠씁니다.
----------------------------------------------------------------------------------------------------------------
Class c = String.class;
Class[] argType = new Class[]{String.class};
Constructor con = c.getConstructor(argType);
Object[] initArg = new Object[]{"Hello World"};
Object obj = con.newInstance(initArg);
if(obj instanceof String){
System.out.println("String형이 맞습니다.:" + obj);
}
else {
System.out.println("Vector형이 아닙니다.");
}
----------------------------------------------------------------------------------------------------------------
처음예제와는 다르게 두번째 예제에선 java.lang.String 클래스의 생성자 리플렉션 예제 입니다.
Class c = String.class; // String 클래스를 클래스 타입으로 케스팅한 것입니다.
참고로, 자바의 모든 객체는 Class 입니다. (프리미티브 타입도 마찬가지 입니다)
그러니까 Class 를 통해 리플렉션을 할 수 있는 것이겠죠...
Class[] argType = new Class[]{String.class};
String 클래스를 클래스 베열에 등록 합니다.
현재는 리플렉션 대상이 String 클래스 하나이지만, 여러 개의 클래스를 동시에 리플렉션 할수도 있겠죠
그래서 배열로 Class를 선언한 것입니다.
Constructor con = c.getConstructor(argType);
클래스배열 argType 에서 생성자들만 잡아옵니다.
String 클래스는 인자가 없는것과, 인자가 있는것 두가지의 생성자가 존재합니다. 그쵸?
new String(); 과 new String("인자있음"); 이 그것입니다.
이것이 메서드 오버로딩 이라고 다들 알고 있을 겁니다.
Object[] initArg = new Object[]{"Hello World"};
파라미터를 설정하고 있습니다.
클래스를 리플렉션을 통해 생성자로 클래스를 인스턴스화 할때
메서드(생성자) 오브로딩을 통해 인스턴스화 하려고 파라미터를 설정하고 있습니다.
이건 new String("인자있음"); 에서 initArg 이 "인자있음" 이 되는 것입니다.
리플렉션을 통해서 아규먼트를 세팅할경우에 이처럼 Class[] 배열로 설정하게 됩니다.
아규먼트는 여러타입의 여러 인자가 올수 있기때문입니다.
Object obj = con.newInstance(initArg);
최종적으로 String 클래스가 인스턴스화 되었습니다.
이코드는 new String("인자있음"); 과 동일합니다.
// 인스턴스 객체의 비교
if(obj instanceof String){
System.out.println("String형이 맞습니다.:" + obj);
}
else {
System.out.println("String 형이 아닙니다."); // 여기 오타나셨네요
}
참고하시기 바랍니다.
[출처] [JAVA] 자바 Reflection의 문법에서 질문|작성자 xxyyzzxyz
http://blog.naver.com/xxyyzzxyz?Redirect=Log&logNo=22421871