책에서는 리플렉션을 잘 다루지 않는다.
사실 어느 경우에 사용하는지 아직 감도 안잡힌다.
간단하게 짚고 넘어가자.
대표적으로 스프링, 하이버네이트 등에서 Reflection을 사용한다고 한다.
Reflection은 클래스의 구조를 개발자가 확인할 수 있고 값을 가져오거나 메소드를 호출하는데 사용할 수 있다고 한다.
Reflection을 확인하기 좋은 예제를 하나 소개하겠다.
아래는 코딩테스트를 준비하면서 사용한 코드이다. 적절한 입력을 받고 이를 처리하는 코드인데 이에 대해서 main의 코드 맨 마지막에서 Reflection을 사용해서 직접 값을 출력해보았다.
package 문제풀이.BOJ.문자열.구현;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Set;
public class boj_2607 {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
ArrayList<String> arr = new ArrayList<>();
for(int i = 0; i < N; i++){
arr.add(br.readLine());
}
int result = 0;
String firstStr = arr.get(0);
for(int i = 1; i < arr.size(); i++){
if(isSimilar(firstStr, arr.get(i))){
result++;
}
}
System.out.println(result);
Class c = Class.forName("문제풀이.BOJ.문자열.구현.boj_2607");
Method[] m = c.getDeclaredMethods();
for(int i = 0; i < m.length; i++){
Method m1 = m[i];
System.out.println("name: " + m1.getName());
System.out.println("declare Class: " + m1.getDeclaringClass());
Class[] gpt = m1.getParameterTypes();
for(int j = 0; j < gpt.length; j++){
System.out.println("Param: " + gpt[j]);
}
}
}
public static boolean isSimilar(String str1, String str2){
// System.out.printf("compare: %s %s\n", str1, str2);
if(str1.equals(str2)){
return true;
}
int[] str1arr = new int[26];
int[] str2arr = new int[26];
for(int i = 0; i < str1.length(); i++){
str1arr[str1.charAt(i) - 'A']++;
}
for(int i = 0; i < str2.length(); i++){
str2arr[str2.charAt(i) - 'A']++;
}
int wordDiff = 0;
for(int i = 0; i< 26; i++){
if(Math.abs(str1arr[i] - str2arr[i]) >= 2){
return false;
}
if(str1arr[i] != str2arr[i]){
wordDiff++;
}
}
if(wordDiff > 2){
return false;
}
return true;
}
}
결과는 아래와 같이 출력된다.
Param: 으로 출력된 부분에 String array로 받고 있는 상태라는 걸 알 수 있다. 또한 isSimilar라는 메소드가 있음을 확인할 수 있다.
name: main
declare Class: class 문제풀이.BOJ.문자열.구현.boj_2607
Param: class [Ljava.lang.String;
name: isSimilar
declare Class: class 문제풀이.BOJ.문자열.구현.boj_2607
Param: class java.lang.String
Param: class java.lang.String
Process finished with exit code 0
Reflection은 무분별하게 사용하지 않는게 좋다고 한다.
Reflection의 단점을 살펴보자면 아래와 같다.
1. 성능 오버헤드: 리플렉션에는 동적으로 해석되는 유형이 포함되서 JVM 최적화를 수행할 수 없다고 한다. 그래서 비 리플렉션 작업보다 성능이 많이 떨어진다고 한다. (성능이 중요한 어플리케이션에는 가급적이면 사용하지 말자.)
2. 보안: 보안적으로 좋지 않다고 한다.
3. 캡슐화 저해: 리플렉션이 private 한 속성이나 메소드에 액세스할 수 있는 것처럼 비 리플렉션 코드에서 작동하지 않는 코드를 수행할 수 있어서 예기치 못한 부작용이 발생할 수 있다고 한다. 또한 플랫폼 업그레이드 시에도 동작이 변경될 수 있다고 한다.
아래 블로그에서 많은 도움을 받았습니다.
감사합니다.
https://medium.com/msolo021015/%EC%9E%90%EB%B0%94-reflection%EC%9D%B4%EB%9E%80-ee71caf7eec5
https://codechacha.com/ko/reflection/
'Java' 카테고리의 다른 글
[Java] 객체지향 디자인패턴 (0) | 2021.01.02 |
---|---|
[Java] 객체지향 UML (0) | 2021.01.02 |
[이것이 자바다] 자바 네트워크2 공부 정리 (0) | 2021.01.01 |
[이것이 자바다] 자바 NIO 공부 정리 (0) | 2020.12.30 |
[이것이 자바다] 자바 네트워크1 공부 정리 (0) | 2020.12.27 |