자바에서는 클래스와 인터페이스의 정보(meta 정보)를 Class 객체
를 이용해서 관리합니다. 이 점을 이용해서 런타임 중에 Class 객체에 접근해서 정보를 수정하거나 읽어낼 수 있는데요. 이러한 기술을 리플렉션(reflection)
이라고 부릅니다.
메타 정보에는 패키지, 타입, 클래스, 생성자, 멤버 변수, 메소드 등이 있습니다.
이러한 Class 객체
에는 3가지 방법으로 접근할 수 있습니다.
Class cls = 클래스명.class;
Class cls = Class.forName(패키지.클래스명); //클래스를 통해 얻는 방식(1번과 2번)
Class cls = 참조변수.getClass(); //객체를 통해 얻는 방식
패키지에 대한 정보는 세 가지 메소드를 통해 얻을 수 있습니다.
예시를 위해 다음과 같은 파일 구조를 하나 만들었습니다.subPackage
하위에 subsubPackage
가 있고, 이 패키지에 Hello
라는 클래스가 존재하는 형태입니다.
public class Main {
public static void main(String[] args) {
Class cls = Hello.class; //Hello 클래스의 정보 취득
System.out.println(cls.getPackage()); //패키지 정보 출력
System.out.println(cls.getSimpleName()); //타입(클래스) 정보 출력
System.out.println(cls.getName()); //패키지 정보와 타입 정보 출력
}
}
타입(인터페이스 또는 클래스)의 멤버들에 대한 정보는 다음 메소드들을 통해 얻을 수 있습니다.
메소드 앞에 타입을 명시한 것은 해당 메소드들이 결과를 배열의 형태로 반환한다는 것을 알려드리기 위함입니다.
참고로 Declared가 빠진 메소드들이 있는데, Declared가 없는 메소드들은
public
으로 선언된 멤버들만 가져옵니다.
위 코드에서 사용했던 것들을 그대로 다시 사용합니다. Hello 클래스에 다음과 같이 멤버 변수, 생성자, 메소드를 추가했습니다.
public class Hello {
private int HELLO = 0;
Hello () {}
public void sayHello() {
System.out.println("Hello");
}
}
그리고 이 중 생성자에 대한 정보만 가져오도록 하겠습니다.
public class Main {
public static void main(String[] args) {
Class cls = Hello.class;
Constructor[] cons = cls.getDeclaredConstructors();
System.out.println(cons[0]);
}
}
생성자에 대한 정보가 제대로 출력되었습니다.
Class 객체
는 가져온 객체의 경로에대한 정보도 가지고 있습니다. 따라서 상대 경로를 통해 디렉토리의 특정 위치에 있는 파일에 대한 정보를 얻을 수도 있습니다.
getResource(파일경로)
를 이용하면 해당 파일의 경로에 대한 정보를 취득할 수 있습니다.