[Java] Java Reflection API

2022. 5. 16. 16:44JAVA/Overview

1. Reflection API란 무엇인가?

Reflection API는 구체적인 클래스 타입을 알지 못해도 그 클래스의 정보(메서드, 타입, 변수 등등)에 접근할 수 있게 해주는 자바 API입니다.

 

2. Reflection API 사례

public class Person {
	private String name;
	private int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Object obj = new Person("김용환", 20); // Object 클래스는 Person 클래스의 조상 클래스여서
											 // obj 참조변수는 Person 인스턴스를 가리킬 수 있음 (다형성)
//		obj.getName(); // obj 인스턴스는 Object 타입이기 때문에 
					   // Object 클래스에 존재하는 멤버(필드멤버, 메서드)만을 참조할 수 있음
		
		Class<Person> person = Person.class;
		Method getName = person.getMethod("getName");
		
		// Method.invoke(Object obj, Object... args)
		// Method.invoke(메서드를 실행시킬 인스턴스, 해당 메서드에 넘길 인자)
		String name = (String) getName.invoke(obj, null);
		System.out.println(name);	// Expected Output : 김용환
	}
}

위 예제에서 obj 인스턴스의 클래스 타입은 Object 타입이여서 모든 클래스의 인스턴스를 가리킬 수 있지만 Object 내의 멤버만을 참조할 수 있습니다. 왜나하면 컴파일러는 해당 인스턴스의 구체적인 클래스를 모르면 해당 클래스의 멤버(필드 멤버, 메서드)에 접근할 수 없기 때문입니다. 하지만 Reflection API를 사용하면 Object 클래스 타입의 참조 변수여도 해당 참조변수가 가리키고 있는 인스턴스의 구체적인 멤버를 참조할 수 있습니다.

 

Class<Person> person = Person.class;
Method getName = person.getMethod("getName");

위와 같이 Person 클래스 정보를 저장하여 해당 클래스의 getName 메서드를 참조하여 Method 타입의 참조변수에 저장합니다. 여기서 Method 클래스가 Reflection API중 하나입니다.

 

String name = (String) getName.invoke(obj, null);
  • Method.invoke(Object obj, Object... args) : Method.invoke(메서드를 실행시킬 인스턴스, 해당 메서드에 넘길 인자)
  • obj 인스턴스를 이용해서 getName 메서드를 수행시킵니다.

어떻게 이러한 수행이 가능할까?

자바에서는 JVM이 실행되면 사용자가 작성한 자바 코드가 컴파일러를 거쳐서 바이트 코드로 변환되어 static 영역에 저장됩니다. Reflection API는 이 정보를 활용하여 수행시킵니다. 그래서 클래스 이름만 알고 있다면 언제든 static 영역에 접근하여 정보를 가져올 수 있습니다.

 

Reflection API의 사용사례

  • Spring Framework의 Spring Container의 BeanFactory
  • Spring Data JPA
  • Hibernate

 

References

source code & example code : https://github.com/yonghwankim-dev/effective_java/tree/master/src/role3/reflection
Guide to Java Reflection
Reflection API 간단히 알아보자.