반응형
어쩌다 Reflection
프로젝트를 진행하다보면 VO 나 DTO 에 있는 column1, column2, column3, ... , column100 이런 형태의 필드에 값을 단순하게 setter 를 이용해 값을 채워줘야할 때가 있다
이런 건 그냥 반복문 돌려서 "setColumn"+(i)+"("+value+")" 이렇게 처리해도 될 것 같은데...
라는 생각에 Reflection 을 접하게 되었다.
쉽게 말해 문자열로 자바 클래스 메서드를 실행시키고 싶다! 라는 마음으로 접하게 된 것이 Reflection 이다.
Reflection 개념
- 객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법
- 투영 반사
Reflection 사용
아래 소스 코드와 같이 Vo Class 를 생성하고 aa1 ~ aa20 까지 생성한다.
// vo class 생성
public class Vo {
private String aa1 ;
private String aa2 ;
private String aa3 ;
private String aa4 ;
private String aa5 ;
private String aa6 ;
private String aa7 ;
private String aa8 ;
private String aa9 ;
private String aa10;
private String aa11;
private String aa12;
private String aa13;
private String aa14;
private String aa15;
private String aa16;
private String aa17;
private String aa18;
private String aa19;
private String aa20;
public String getAa1() {
return aa1;
}
public void setAa1(String aa1) {
this.aa1 = aa1;
}
// ... 너무 길어서 getAa2 ~ setAa19 까지는 생략했습니다.
public String getAa20() {
return aa20;
}
public void setAa20(String aa20) {
this.aa20 = aa20;
}
@Override
public String toString() {
return "Vo [aa1=" + aa1 + ", aa2=" + aa2 + ", aa3=" + aa3 + ", aa4=" + aa4 + ", aa5=" + aa5 + ", aa6=" + aa6
+ ", aa7=" + aa7 + ", aa8=" + aa8 + ", aa9=" + aa9 + ", aa10=" + aa10 + ", aa11=" + aa11 + ", aa12="
+ aa12 + ", aa13=" + aa13 + ", aa14=" + aa14 + ", aa15=" + aa15 + ", aa16=" + aa16 + ", aa17=" + aa17
+ ", aa18=" + aa18 + ", aa19=" + aa19 + ", aa20=" + aa20 + "]";
}
}
Vo Class 를 Reflection 할 Test Class 생성
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) {
try {
java.lang.Class c = java.lang.Class.forName( "Vo" ); // 클래스 정보
Object obj = c.newInstance(); // 클래스 객체 생성
java.lang.reflect.Method[] m1 = c.getMethods(); // 클래스 내 public method 를 가져온다.
for ( java.lang.reflect.Method m : m1 ) {
String mName = m.getName();
if ( mName.indexOf( "set" ) > -1 ) {
Class[] param = {String.class};
java.lang.reflect.Method execM = c.getMethod( mName , param);
execM.invoke( obj , "A" );
}
}
System.out.println( obj.toString() );
java.lang.reflect.Method[] m2 = c.getDeclaredMethods(); // private 포함 클래스 내부에서 선언한 함수를 찾아온다.
for ( java.lang.reflect.Method m : m2 ) {
String mName = m.getName();
if ( mName.indexOf( "set" ) > -1 ) {
Class[] param = {String.class};
java.lang.reflect.Method execM = c.getMethod( mName , param);
execM.setAccessible( true ); // 필드나 메서드의 접근제어 지시자에 의한 제어를 변경
execM.invoke( obj , "A" );
}
}
System.out.println( obj.toString() );
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
private method 를 사용하기 위해서는 반드시 아래 옵션을 추가하시기 바랍니다.
method.setAccessible( true );
// 실행 결과
Vo [aa1=A, aa2=A, aa3=A, aa4=A, aa5=A, aa6=A, aa7=A, aa8=A, aa9=A, aa10=A, aa11=A, aa12=A, aa13=A, aa14=A, aa15=A, aa16=A, aa17=A, aa18=A, aa19=A, aa20=A]
Vo [aa1=A, aa2=A, aa3=A, aa4=A, aa5=A, aa6=A, aa7=A, aa8=A, aa9=A, aa10=A, aa11=A, aa12=A, aa13=A, aa14=A, aa15=A, aa16=A, aa17=A, aa18=A, aa19=A, aa20=A]
Reflection 사용 후기
제가 작성한 내용은 어디까지나 Method invoke 입니다
java Reflection 을 검색하면 많은 정보가 나옵니다.
모든 정보를 다 사용해본 것은 아니기 때문에 사용하기 전에 공부는 필수입니다.
반응형
'java' 카테고리의 다른 글
[Java] 2. 자료형 (0) | 2022.05.13 |
---|---|
[Java] 1. 변수 (0) | 2022.05.13 |
[Java] Escape 문자 (0) | 2021.01.18 |
[로직] 반복문 없이 반복하기 (0) | 2021.01.12 |
[Java] DB Connection (0) | 2021.01.12 |
댓글