-
Notifications
You must be signed in to change notification settings - Fork 0
유동근, 박혜성 리플랙션
런타임에 클래스의 이름, 메서드, 생성자, 필드와 같은 메타 정보를 가져오기 위한 API입니다.
자바뿐만 아니라 컴파일되어 기계어로 실행되지 않는 언어들은 리플렉션 기능을 가지고 있씁니다.
getFields()
와 같은 메서드는 접근 제어가 public인 것만 가져오지만 getDeclaredxxx()
와 같은 메서드는 접근 제어자가 private 인 것까지 모두 가져옵니다.
생성자를 가져오기 위해서는 getConstructors()
와 같이 Constructor
클래스를 가져올 수 있는 API를 이용할 수 있습니다.
인스턴스의 생성을 위해 class.newInstance()
를 통해 생성할 수 있지만 java 9버전 부터 사용되지 않습니다. 다르게는 getContructor()
메서드를 이용하여 생성자를 가져오고, constructor.newInstance()
를 통해 객체를 생성하는 방법이 있습니다. getContructor()
의 인자로는 클래스 객체를 전달할 수 있으며, 아무 것도 전달하지 않는 경우 기본 생성자를 조회해옵니다. 만약 전달한 인자에 해당하는 생성자가 존재하지 않는 경우 예외가 발생합니다.
예를 들어 User
의 인스턴스를 생성한다고 할 때, 다음과 같이 이용할 수 있습니다.
Class<User> userClass = User.class;
Constructor<User> defulatConstructor = userClass.getConstructor();
User user = defulatConstructor.newInstance();
Constructor<User> anotherConstructor = userClass.getConstructor(String.class);
User anotherUser = anotherConstructor.newInstance("username");
이 때, 가져온 생성자에 맞지 않는 인자를 newInstance()
호출시에 전달하면 예외가 발생합니
메서드를 가져오기 위해서는 getMethods()
와 같이 Method
객체를 가져올 수 있는 API를 이용할 수 있습니다. 이렇게 가져온 메서드를 실행하려면 method.invoke()
를 호출을 통해 가능합니다. 이 때 인자로 클래스의 인스턴스를 인자로 전달해야 합니다.
예를 들면 다음과 같습니다.
User user = new User();
Class<User> userClass = User.class;
Method helloMethod = userClass.getMethod("hello");
helloMethod.invoke(user);
필드를 가져오기 위해서는 getFields()
와 같이 Field
객체를 가져올 수 있는 API를 이용할 수 있습니다. getDeclaredFields()
를 이용하여 가져온 private 필드의 경우 setAccessible()
을 true로 설정하면 필드의 값을 변경할 수 있습니다.
예를 들어 다음과 같이 field.set(인스턴스, 값)
으로 호출할 수 있습니다.
Field age = studentClass.getDeclaredField("age");
age.setAccessible(true);
age.set(student, 100);
Constructor
, Field
, Method
타입은 signature
라는 필드를 가지고 있습니다. 해당 필드는 제네릭 타입을 사용하는 경우에 설정되는 정보입니다. 만약 제네릭을 사용하지 않으면 null 값을 가집니다.