Java

[Java] 자바 리플렉션 - java Reflection이란?

Razelo 2021. 1. 2. 14:55

책에서는 리플렉션을 잘 다루지 않는다.

 

사실 어느 경우에 사용하는지 아직 감도 안잡힌다.

 

간단하게 짚고 넘어가자. 


대표적으로 스프링, 하이버네이트 등에서 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

 

자바 Reflection이란?

많은 입문용 자바 서적에서 잘 다루지 않는 Reflection이라는 개념에 대해서 알아보려고 합니다.

medium.com

 

https://codechacha.com/ko/reflection/

 

Java - Reflection 쉽고 빠르게 이해하기

자바의 리플렉션(Reflection)은 클래스, 인터페이스, 메소드들을 찾을 수 있고, 객체를 생성하거나 변수를 변경할 수 있고 메소드를 호출할 수도 있습니다. Reflection은 Class, Constructor, Method, Field와 같

codechacha.com

 

반응형