만약 API 버전에 따라서 package의 경로가 다를 때 클래스작업을 해야한다면 어떻게 해야할까요?
그럴 경우에는 reflection을 사용해 볼 수 있습니다.
reflection이란 Java에서 package 경로(문자열 형태)로 클래스를 불러오고 작업하는 것을 쉽게 해주는 것이라고 볼 수 있습니다.
먼저 불러올 클래스를 만들어 주겠습니다.
package net.test;
public class Test {
public Test() {}
public Test(String msg) { System.out.println(msg); }
public class Test2 {}
}
이런식으로 간단하게 Test 클래스를 생성했습니다.
다음으로는 Main 클래스를 만들어 클래스를 불러오겠습니다.
package net.test;
public class Main {
public static void main(String[] args) {
try {
Class<?> test = Class.forName("net.test.Test");
Class<?> test2 = Class.forName("net.test.Test$Test2");
} catch (ClassNotFoundException e) { }
}
}
Main 클래스를 생성하고 전에 만들었던 Test 클래스를 불러왔습니다.
Class.forName("경로") 의 형태로 클래스를 불러올 수 있으며,
클래스 안에 있는 클래스의 경우에는 Class.forName("[클래스 경로]$[내부 클래스 이름]")
의 형태로 불러올 수 있습니다.
클래스가 존재하지 않는다면 ClassNotFoundException 오류가 나니 주의해주세요.
이것의 문제로는 정확한 클래스 형태로 가져올 수 없다는 것입니다.
- Class<Test> test = Class.forName("net.test.Test");
물론 형변환으로 가능은 하나, 이렇게 되면 동적으로 클래스를 불러오는 이유가 없죠.
다음으로는 new 연산자를 사용하는 방법입니다.
이것은 굉장히 쉽습니다.
try {
Object testObject = test.newInstance();
test.getConstructor(String.class).newInstance("TEST");
} catch (InstantiationException | IllegalAccessException e) { }
.newInstance() 를 사용하면 new 연산자를 사용한 것과 같은 효과를 얻을 수 있죠. Object 형태로 반환되게 됩니다.
그런데 생성자중에 매개변수가 있는 생성자를 호출할려면 어떻게 해야할까요?
바로 getConstructor() 을 사용하면 되는데 생성자의 파라미터 클래스들을 입력해주면 됩니다.
위의 Test클래스 에서는 파라미터로 String을 받으니
getConstructor(String.class) 로 String 파라미터를 가지는 생성자를 가져올 수 있겠죠.
- 파라미터가 string, string, int 등 여러 다른 형태도 마찬가지입니다.
- 클래스.getConstructor(String.class, String.class, int.class) 로 가져올 수 있습니다.
2부에는 이 불러온 클래스로 메소드 호출 및, 변수 가져오는 법을 작성할 예정입니다.