자바 리플렉션 메커니즘 완벽 가이드

리플렉션 메커니즘의 개념

리플렉션 메커니즘은 프로그램 실행 중에 임의의 클래스에 대해 모든 속성과 메서드를 획득하고, 임의의 객체에 대해 임의의 메서드를 호출할 수 있는 기능을 의미합니다. 이러한 방식으로 클래스와 객체의 정보를 동적으로 획득하고, 객체의 메서드를 동적으로 호출하는 기술을 자바 리플렉션 메커니즘이라고 부릅니다.

자바 리플렉션 API

자바의 리플렉션 API는 주로 프로그램에서 클래스, 인터페이스 또는 객체 등을 동적으로 생성하는 데 사용됩니다. 주요 API는 다음과 같습니다:

  • Class 클래스: 클래스의 속성, 메서드 등의 정보를 획득하는 데 사용됩니다.
  • Field 클래스: 클래스의 멤버 변수를 나타내며, 클래스 내 속성 값을 획득하거나 설정하는 데 사용됩니다.
  • Method 클래스: 클래스의 메서드를 나타내며, 메서드에 대한 설명 정보를 획득하거나 특정 메서드를 실행하는 데 사용됩니다.
  • Constructor 클래스: 클래스의 생성자를 나타냅니다.

리플렉션의 절차

리플렉션의 절차는 다음과 같습니다:
(1) 작업하려는 클래스의 Class 객체를 획득합니다. 이 Class 객체는 리플렉션의 핵심이며, 이를 통해 클래스의 모든 메서드를 호출할 수 있습니다.
(2) Class 객체가 대응하는 클래스에 정의된 메서드를 호출합니다. 이는 리플렉션의 사용 단계입니다.
(3) 리플렉션 API를 사용하여 클래스의 속성과 메서드 정보를 획득하고 호출합니다.

Class 객체를 획득하는 3가지 방법은 다음과 같습니다:

방법 1: 객체의 getClass() 메서드를 호출하여 해당 클래스의 Class 객체를 획득합니다.

Person person = new Person();
Class<?> clazz = person.getClass();

방법 2: 클래스의 .class 속성을 호출하여 해당 클래스의 Class 객체를 획득합니다.

Class<?> clazz = Person.class;

방법 3: Class 클래스의 정적 메서드 forName()을 호출하여 해당 클래스의 Class 객체를 획득합니다. 이 방법이 가장 안전하고 성능도 좋습니다.

Class<?> clazz = Class.forName("hello.java.reflect.Person");

Class 객체를 획득한 후, Class 클래스의 메서드를 사용하여 해당 클래스의 메서드와 속성을 획득하고 확인할 수 있습니다. 예제 코드는 다음과 같습니다:

// 1. Person 클래스의 Class 객체 획득
Class<?> targetClass = Class.forName("hello.java.reflect.Person");

// 2. 모든 메서드 정보 획득
Method[] methods = targetClass.getDeclaredMethods();
for (Method method : methods) {
    System.out.println(method.toString());
}

// 3. 모든 멤버 변수(필드) 정보 획득
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field.toString());
}

// 4. 모든 생성자 정보 획득
Constructor<?>[] constructors = targetClass.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println(constructor.toString());
}

객체 생성의 두 가지 방식

객체를 생성하는 두 가지 방식은 다음과 같습니다:

  • 방법 1: Class 객체의 newInstance() 메서드를 사용하여 해당 클래스의 인스턴스를 생성합니다. 이 방법은 해당 클래스에 기본(매개변수 없는) 생성자가 있어야 합니다. (Java 9부터는 권장되지 않습니다.)
  • 방법 2: 먼저 Class 객체를 사용하여 특정 Constructor 객체를 획득한 후, Constructor 객체의 newInstance() 메서드를 호출하여 인스턴스를 생성합니다. 이 방법을 사용하면 원하는 생성자를 선택하여 객체를 생성할 수 있습니다.

객체 생성 예제 코드입니다:

// 방법 1: Class.forName()과 newInstance() 사용
Class<?> personClass = Class.forName("hello.java.reflect.Person");
Person person1 = (Person) personClass.newInstance(); // 기본 생성자 필요

// 방법 2: Constructor 사용
Constructor<?> constructor = personClass.getDeclaredConstructor(String.class, String.class, int.class);
Person person2 = (Person) constructor.newInstance("이사", "남성", 20);

Method 클래스의 invoke 메서드

Method 클래스는 클래스나 인터페이스에 있는 특정 메서드에 접근하는 방법에 대한 정보를 제공합니다. 그렇다면 실행 중인 코드에서 어떻게 해당 메서드를 동적으로 호출할 수 있을까요? 정답은 Methodinvoke() 메서드를 호출하는 것입니다. invoke() 메서드를 통해 동적 호출을 구현할 수 있으며, 예를 들어 매개변수를 동적으로 전달하여 메서드를 파라미터화할 수 있습니다. 과정은 다음과 같습니다.

(1) Method 객체 획득: Class 객체의 getMethod(String name, Class<?>... parameterTypes)를 호출하여 Method 객체를 반환받습니다. 이 객체는 해당 Class 객체가 나타내는 클래스나 인터페이스에 정의된 특정 public 멤버 메서드를 설명합니다. name 매개변수는 메서드 이름을 지정하는 String 타입입니다. parameterTypes 매개변수는 메서드의 매개변수 타입을 선언된 순서대로 나열한 Class 객체 배열입니다. parameterTypesnull이면 빈 배열로 처리됩니다.

(2) invoke 메서드 호출: Method 객체의 invoke() 메서드를 호출하여 함수를 동적으로 실행합니다. invoke() 메서드의 사용 예제 코드입니다:

// 1단계: Person 클래스의 Class 객체 획득
Class<?> personClass = Class.forName("hello.java.reflect.Person");

// 2단계: setName(String) 메서드에 해당하는 Method 객체 획득
Method setNameMethod = personClass.getMethod("setName", String.class);

// 3단계: 기본 생성자 획득
Constructor<?> constructor = personClass.getConstructor();

// 4단계: 생성자를 통해 Person 객체 생성
Object personObject = constructor.newInstance();

// 5단계: invoke() 호출하여 setName 메서드 동적 실행
// personObject 객체의 setName 메서드를 호출하면서 "alex"를 인자로 전달
setNameMethod.invoke(personObject, "alex");

위 코드는 먼저 Class.forName()을 통해 Person 클래스의 Class 객체를 획득합니다. 그런 다음 Person 클래스의 Class 객체에서 getMethod("setName", String.class)를 호출하여 setName 메서드를 나타내는 Method 객체를 얻습니다. 이어서 Class 객체를 사용하여 기본 생성자를 나타내는 Constructor 객체를 획득하고, newInstance()를 호출하여 객체를 생성합니다. 마지막으로 method.invoke()를 호출하여 동적 호출을 구현함으로써, 리플렉션을 통해 클래스의 객체를 동적으로 생성하고 해당 메서드를 호출합니다.

태그: java 리플렉션 Class Method Constructor

7월 3일 23:05에 게시됨