[Java] 자바 리플렉션

TPark·2020년 5월 23일
3

면접대비

목록 보기
1/5

Reflection 이란

구체적인 클래스 타입을 알지 못해도 해당 클래스의 객체 생성, 메소드, 타입, 변수들에 접근할수 있도록 도와주는 Java API

언제 필요한가

동적으로 클래스를 사용해야 할때 필요하다. 즉, 작성 시점에는 어떤 클래스를 사용해야 할지 모르는 경우, 런타임 시점에서 클래스를 가져와서 실행해야 하는 경우에 사용된다. 대표적으로 IntelliJ의 자동완성이나 Spring 프레임워크의 어노테이션 같은 기능들이 리플렉션을 이용해서 프로그램 실행 중 동적으로 클래스 정보를 가져와서 사용하는 예이다.

어떻게 가능한가

자바 클래스 파일은 프로그램 생성시에 힙영역에 저장된다. 그래서 클래스 이름만 알고 있다면 언제든 이 영역에 들어가서 클래스의 정보를 가져올수 있다.

예제


public class Parent {
	public final static int x = 1;
	void hi() {
		System.out.println("parent hi");
	}
	
	public int bye(int x, boolean y) throws IndexOutOfBoundsException {
		System.out.println(x + ", " + y);
		return 0;
	}
}
public class Main extends Parent {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
		Class cls = Class.forName("Parent");
		
		// declae if object is instance of cls
		System.out.println(cls.isInstance(new Object()));
		System.out.println(cls.isInstance(new Main()));
		System.out.println();

		// Find class methods
		Method[] methList = cls.getDeclaredMethods();
		for (Method m : methList) {
			System.out.println("method: " + m.getName());
			System.out.println("class: " + m.getDeclaringClass());
			
			System.out.println("params");
			Parameter[] parList = m.getParameters();
			for (Parameter p : parList) {
				System.out.println("type: " + p.getType());
				System.out.println("name: " + p.getName());
			}
			
			Class<?>[] eList = m.getExceptionTypes();
			for (Class e : eList) {
				System.out.println("exception: " + e);
			}
			System.out.println("return type = " + m.getReturnType());
			System.out.println();
		}
		
		// Find class constructors
		Constructor[] consts = cls.getDeclaredConstructors();
		
		// Find class fields
		Field[] fields = cls.getDeclaredFields();
		System.out.println(fields[0].getName() + ", " + fields[0].getType());
		System.out.println(Modifier.toString(fields[0].getModifiers()));
		
		// Create new instance
		Object[] parList = null;
		consts[0].newInstance(parList);
		
		// Run methods by reflection info
		Class partypes[] = new Class[2];
		partypes[0] = Integer.TYPE;
		partypes[1] = Boolean.TYPE;
		
		Object[] argList = new Object[2];
		argList[0] = new Integer(0);
		argList[1] = new Boolean(true);

		Method m = cls.getMethod("bye", partypes);
		m.invoke(consts[0].newInstance(parList), argList);
	}
}

실행결과

false
true

method: bye
class: class Parent
params
type: int
name: arg0
type: boolean
name: arg1
exception: class java.lang.IndexOutOfBoundsException
return type = int

method: hi
class: class Parent
params
return type = void

x, int
public static final
0, true

0개의 댓글