[Java] 리플렉션

Bam·2024년 3월 11일
0

Java

목록 보기
58/98
post-thumbnail

리플렉션

자바에서는 클래스와 인터페이스의 정보(meta 정보)를 Class 객체를 이용해서 관리합니다. 이 점을 이용해서 런타임 중에 Class 객체에 접근해서 정보를 수정하거나 읽어낼 수 있는데요. 이러한 기술을 리플렉션(reflection)이라고 부릅니다.

메타 정보에는 패키지, 타입, 클래스, 생성자, 멤버 변수, 메소드 등이 있습니다.

이러한 Class 객체에는 3가지 방법으로 접근할 수 있습니다.

Class cls = 클래스명.class;
Class cls = Class.forName(패키지.클래스명);	//클래스를 통해 얻는 방식(1번과 2번)
Class cls = 참조변수.getClass();	//객체를 통해 얻는 방식

패키지 정보 취득

패키지에 대한 정보는 세 가지 메소드를 통해 얻을 수 있습니다.

  • getPackage(): 패키지 정보 취득
  • getSimpleName(): 패키지를 제외한 타입(인터페이스 또는 클래스) 정보 취득
  • getName(): 패키지 정보 + 타입 정보 취득

예시를 위해 다음과 같은 파일 구조를 하나 만들었습니다.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());	//패키지 정보와 타입 정보 출력
    }
}


타입의 멤버 정보 취득

타입(인터페이스 또는 클래스)의 멤버들에 대한 정보는 다음 메소드들을 통해 얻을 수 있습니다.

  • Constructor[] getDeclaredConstructors(): 생성자 정보 취득
  • Field[] getDeclaredFields(): 멤버 변수 정보 취득
  • Method[] getDeclaredMethods(): 메소드 정보 취득

메소드 앞에 타입을 명시한 것은 해당 메소드들이 결과를 배열의 형태로 반환한다는 것을 알려드리기 위함입니다.

참고로 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(파일경로)를 이용하면 해당 파일의 경로에 대한 정보를 취득할 수 있습니다.

0개의 댓글