Reflection

김회민·2023년 2월 11일
0

Java

목록 보기
10/16

Reflection이란?

  • 자바에서 이미 로딩이 완료된 클래스에서 또 다른 클래스를 동적으로 로딩하여 생성자, 맴버 필드, 맴버 메서드 등을 사용할 수 있는 기법이다.
  • 클래스의 패키지 정보, 접근 지정자, 슈퍼 클래스, 애노테이션 등을 얻을 수 있다.
  • 컴파일 시간이 아니라 런 타임에 동적으로 특정 클래스의 정보를 개체화를 통해 분석 및 추출해낼 수 있는 프로그래밍 기법이다.
  • Spring Framework에서 Bean을 등록하고 꺼내올때 사용된다.
    • new AnnotationConfigApplicationContext(AppConfig.class);

사용 방법

  • Class c = Class.forName(”클래스 이름”);
  • Class c = int.class;
  • Class c = Integer.TYPE; // 자바 원시 타입의 경우
  • 클래스의 이름으로부터 인스턴스를 생성할 수 있고, 이를 이용하여 클래스의 정보를 가져올 수 있다.

예제

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Main {
    public static class Member {
        private String name;
        protected int age;
        public String hobby;

        public Member(String name, int age, String hobby) {
            this.name = name;
            this.age = age;
            this.hobby = hobby;
        }

        public void speak(String message) {
            System.out.println("message = " + message);
        }

        private void secret() {
            System.out.println("비밀번호는 1234입니다.");
        }

        @Override
        public String toString() {
            return "Member{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", hobby='" + hobby + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) throws Exception {
        // Instance 생성
        Member member = new Member("새우", 27, "개발");
        
        // Reflection 을 통해 Class 정보를 가져온다.
        Class<? extends Member> memberClass = member.getClass();

        // member Instance Field 접근
        Field[] fields = memberClass.getDeclaredFields();
        for (Field field : fields) {
            // private Field 접근 허용
            field.setAccessible(true);

            // member Instance Field 값 조회하기
            System.out.println(field.get(member));
        }

        // member Instance 첫번째 Field 접근 후 값 변경하기
        fields[0].set(member, "새우2");
        System.out.println(member);

        // member Instance public Method 접근
        Method speakMethod = memberClass.getDeclaredMethod("speak", String.class);
        speakMethod.invoke(member, "리플렉션 테스트"); // member.speak("리플렉션 테스트");

        // member Instance private Method 접근
        Method secretMethod = memberClass.getDeclaredMethod("secret");
        secretMethod.setAccessible(true);
        secretMethod.invoke(member); // member.secret(); 으로 접근 불가능
    }
}
// member Instance Field 값 조회하기
새우
23
개발
// member Instance 첫번째 Field 접근 후 값 변경하기
Member{name='새우2', age=23, hobby='개발'}
// member Instance public Method 접근
message = 리플렉션 테스트
// member Instance private Method 접근
비밀번호는 1234입니다.

왜 사용할까?

  • 실행 시간에 다른 클래스를 동적으로 로딩하여 접근할 때
  • 클래스와 멤버 필드 그리고 메서드 등에 관한 정보를 얻어야할 때
  • 리플렉션 없이도 완성도 높은 코드를 구현할 수 있지만, 사용한다면 조금 더 유연한 코드를 만들 수 있다.

주의점

  • 외부에 공개되지 않는 private 멤버도 Field.setAccessible() 메서드를 true로 지정하면 접근과 조작이 가능하기 때문에 주의해야 한다.

출저

profile
백엔드 개발자 지망생

0개의 댓글