💡 구체적인 클래스 타입을 알지 못해도 그 클래스의 정보(메서드, 타입, 변수)에 접근할 수 있는 자바 API
💡 Method.invoke는 어떤 클래스의 어떤 객체가 가진 어떤 메서드라도 호출할 수 있게 해줌. 리플렉션을 이용하면 컴파일 당시에 존재하지 않던 클래스도 이용할 수 있음.
1. 컴파일 타임 타입 검사가 주는 이점을 하나도 누릴 수 없다.
2. 리플렉션을 이용하면 코드가 지저분하고 장황해진다.
3. 성능이 떨어진다.
/* 방법 1. reflection API로 메소드를 호출하는 방식 👎 */
// Node 클래스의 타입을 찾는다.
Class<?> cls = Class.forName("Node");
// Node 클래스의 생성자를 취득한다.
Constructor<?> constructor = cls.getConstructor();
// 생성자를 통해 newInstance 함수를 호출하여 Node 인스턴스를 생성한다.
Object node = constructor.newInstance();
// Node 클래스의 print함수를 취득한다.
Method method = cls.getMethod("print");
// 취득한 함수에 생성한 인스턴스를 넣고 실행시킨다.
method.invoke(node);
/* 방법 2. 인터페이스를 참조하여 메소드를 호출 👍 */
// 클래스 이름을 Class 객체로 변환
Class<? extends Set<String>> cl = null;
try {
cl = (Class<? extends Set<String>>) Class.forName(args[0]); //비검사 형변환
} catch (ClassNotFoundException e) {
fatalError("클래스를 찾을 수 없습니다.");
}
// 생성자를 얻는다.
Constructor<? extends Set<String>> cons = null;
try {
cons = cl.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
fatalError("매개변수 없는 생성자를 찾을 수 없습니다.");
}
//집합의 인스턴스를 만든다.
Set<String> s = null;
try {
s = cons.newInstance();
} catch (IllegalAccessException e) {
fatalError("생성자에 접근할 수 없습니다.");
} catch (InstantiationException e) {
fatalError("클래스를 인스턴스화할 수 없습니다.");
} catch (InvocationTargetException e) {
fatalError("생성자가 예외를 던졌습니다: " + e.getCause());
} catch (ClassCastException e) {
fatalError("Set을 구현하지 않은 클래스입니다.");
}
//생성한 집합을 사용한다.
s.addAll(Arrays.asList(args).subList(1, args.length));
System.out.println(s);
컴파일 당시에 컬럼명을 알 수 없을 때 사용..
ex) 타 시스템 인터페이스 시에 매칭되는 컬럼명을 코드로 관리함.
Method getter = (new PropertyDescriptor(propertyName, obj.getClass(), "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1), (String)null)).getReadMethod();
try {
// 리플렉션 사용
return getter.invoke(obj);
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException var9) {
var9.printStackTrace();
}
// Client Code
for(String col : cdMap.keySet()){
cdNm = mdCdMap.getOrDefault(invokeGetter(dto, col), "");
result.setCdNm(cdNm)
}