Java Reflection을 이용하여 클래스 정보 객체를 얻어내고 이를 통해 클래스 제어가 가능하다.
com.hacademy.refelection3.Member 클래스를 만들고 예제에서 사용한다.
Member.java
package com.hacademy.reflection3;
public class Member {
private String id;
private String password;
private String nickname;
@Override
public String toString() {
return "Member [id=" + id + ", password=" + password + ", nickname=" + nickname + "]";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Member() {
super();
}
public Member(String id, String password, String nickname) {
super();
this.id = id;
this.password = password;
this.nickname = nickname;
}
}
클래스 정보
특정 클래스에 대한 Class 타입의 객체를 다양한 방법으로 구현할 수 있다.
Test01.java
package com.hacademy.reflection3;
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
Class<? extends Member> a = new Member().getClass();
Class<Member> b = Member.class;
Class<?> c = Class.forName("com.hacademy.reflection3.Member");
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
위의 코드 중에서 객체 없이 설정한 값에 의해 클래스 정보를 불러올 수 있는 방식은 c이다.
Class<?> c = Class.forName("com.hacademy.reflection3.Member");
Class.forName() 은 대상 클래스의 정보를 클래스로더(ClassLoader)에 등록한 뒤 반환하는 명령이다. 이 때, 대상의 static 정보들은 미리 등록된다.
예를 들면 다음과 같이 처리할 수 있다.
Test02.java
package com.hacademy.reflection3;
public class Test02 {
public static void main(String[] args) {
if(args.length != 2)
throw new IllegalArgumentException("usage : java Test02 [basePackage] [className]");
String basePackage = args[0];
String className = args[1];
String fullPath = basePackage+"."+className;
try {
Class<?> c = Class.forName(fullPath);
System.out.println("c = " + c);
}
catch(ClassNotFoundException e) {
System.err.println("잘못된 클래스 경로");
}
}
}
Properties 또는 기타 입출력 방식을 통하여 불러온 정보로도 클래스 정보를 불러올 수 있다.
필드 정보
package com.hacademy.reflection3;
import java.lang.reflect.Field;
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c = Class.forName("com.hacademy.reflection3.Member");
System.out.println("<accessible field list>");
for(Field field : c.getFields()) {
System.out.println(field);
}
System.out.println("<declared all field list>");
for(Field field : c.getDeclaredFields()) {
System.out.println(field);
}
}
}
Field는 접근 가능한 필드와 전체 필드를 조회하는 명령이 각각 존재한다.
getFields() - 상속관계를 포함한 접근 가능한 Field 목록 반환
getDeclaredFields() - 해당 클래스에 명시된 전체 Field 목록 반환
현재 Member 클래스에는 private field만 존재하므로 getFields() 로는 결과가 나오지 않고 getDeclaredFields()로만 결과가 나오는 것을 확인할 수 있다.