본문 바로가기
  • 주니어 개발자의
    RESTful 성장기
Web/Java

Reflection

by 돌건 2022. 1. 25.

Reflection API란?

구체적인 클래스 타입을 알지 못하더라도 해당 클래스의 정보(타입, 필드, 메서드 등)에 접근할 수 있도록 해주는 Java에서 제공하는 API이다.

 

예시

public class Member {

    private String name;
    
    private void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

위와 같은 클래스가 존재할 때, 외부에서 Member class 필드인 name의 값을 직접 수정할 수 없다. 하지만 reflection API를 사용한다면, private 필드와 메서드를 이용할 수 있다.

public class Main {

    public static void main (String[] args) throws Exception {

        Object member = new Member();
        Class memberClass = Member.class;
        
        // Member 클래스에 선언된 모든 메서드들 중, setName이라는 메서드를 반환.
        Method setName = memberClass.getDeclaredMethod("setName", String.class);
		
        // 해당 메서드는 접근 지정자가 private이므로, setAccessible을 통해 외부에서 접근 가능하도록 설정
        setName.setAccessible(true);
        
        // Object 타입의 Member 인스턴스를 이용해 해당 메서드를 실행.
        setName.invoke(member, "hello");

        // getMethod()는 접근 지정자가 public인 메서드를 대상으로 조회
        Method getName = memberClass.getMethod("getName");
        String name = (String) getName.invoke(member, null);

        System.out.println("name = " + name);
    }
}

Reflection API에서 제공하는 클래스 정보를 가져오는 방법에는 크게 3가지가 있다. 

1. 클래스.class
2. 인스턴스.getClass();
3. Class.forName(클래스명);

main 메서드를 보면, 사실 member 변수는 Member 클래스가 가지고 있는 메서드를 이용할 수 없다. Object 타입에는 Member에 정의된 메서드가 존재하지 않기 때문이다. 하지만, Reflection API를 사용한다면 구체적인 클래스 타입을 알지 못하더라도 해당 클래스의 정보에 접근할 수 있게된다. 

또한, private 접근 제어자를 지니더라도 이에 대한 접근 가능 여부를 설정해주면 접근이 가능해진다. 이를 통해 싱글톤 패턴이 적용된 클래스의 경우에도 새로운 인스턴스를 생성할 수 있게 된다. (private 생성자에 접근하여 새로운 인스턴스 생성)

 

 

동작 원리

자바 파일은 컴파일을 통해 바이트 코드(.class)를 생성한다. 클래스 파일 하나당 java.lang.Class 객체를 하나씩 생성하고, Class는 모든 클래스 파일들의 정보를 가지고 있으며 클래스 파일에 함께 저장된다. 모든 클래스 파일들은 해당 클래스를 최초로 사용하는 시점에서 Class Loader를 통해 JVM에 동적으로 로드된다.

최초로 사용하는 시점은 클래스 파일의 클래스 변수/메서드 (static)를 사용할 때를 말한다. 생성자 또한 static 메소드이므로 인스턴스를 생성하게 되면 static 메모리 영역에 동적으로 올라가게 된다. Reflection API는 이 정보를 활용해 클래스의 이름을 통해 static 영역에서 해당 클래스 정보를 조회할 수 있다.

 

단점 및 활용

Reflection이 가진 최대 단점은 성능 오버헤드이다. Reflection은 앞서 말했듯, 런타임에 동적으로 클래스의 정보를 조회하므로 JVM을 최적화할 수 없다. 또한, 예시에서와 같이 private 접근 제어자가 설정되어 있는 인스턴스 변수와 메서드에 접근할 수 있어 데이터의 안전이 위협 받을 수 있다.

따라서, Reflection은 프레임워크와 라이브러리에서 많이 사용된다. Spring Framework에서 Spring Container의 BeanFactory가 대표적이다. Bean은 애플리케이션 런타임에 객체가 호출될 때 동적으로 인스턴스를 생성한다. 이 과정에서 바로 Reflection이 사용되는 것이다.

또 다른 예로, JPA의 Lazy Loading과 Proxy이다. 지연 로딩은 Entity를 조회할 때 연관관계를 지닌 Entity들의 정보를 가져오지 않고, 해당 Entity 클래스를 상속 받아 생성되는 Proxy 객체를 반환한다. 즉, 이 과정에서 Reflection이 사용된다.

 

 

참고

https://tecoble.techcourse.co.kr/post/2020-07-16-reflection-api/

 

Reflection API 간단히 알아보자.

Spring Framework를 학습하다 보면 Java Reflection API를 자주 접하게 된다. 하지만 Reflection API…

tecoble.techcourse.co.kr

https://transferhwang.tistory.com/150

 

[JAVA] 자바 리플렉션(Java Reflection)

리플렉션(Reflection)이란? 구체적인 클래스 타입을 알지 못해도 해당 클래스의 생성자, 메소드, 타입, 변수들에 접근할 수 있도록 도와주는 기본적으로 Java에서 제공하는 API 리플렉션의 필요성? 동

transferhwang.tistory.com

https://irostub.github.io/java/java-static-stack-heap/

 

JAVA/ Static, Stack, Heap 메모리 영역의 이해

JAVA 메모리 영역의 이해

irostub.github.io

https://velog.io/@sa1341/JPA-Proxy

 

JPA Proxy

얼마전에 AOP 관련된 글들을 살펴보다가 프록시를 알게되어서 스프링 AOP에서 프록시가 어떻게 동작하는지에 대해서도 간단히 살펴보았습니다. 하지만 역시 이 프록시라는 녀석은 JPA에서 지연로

velog.io

 

'Web > Java' 카테고리의 다른 글

Collections Framework (1) ArrayList, LinkedList  (0) 2022.02.08
직렬화와 역직렬화  (0) 2022.02.07
Statement vs PreparedStatement  (0) 2021.10.11
GC (Garbage Collector)  (0) 2021.09.05
JVM (Java Virtual Machine)  (0) 2021.09.01

댓글