티스토리 뷰

java

[JAVA] Reflection

구삼칠오 2022. 1. 7. 00:46

Reflection 이란?

Reflection은 Class<T>라는 API를 사용해 클래스, 메소드, 필드등에 대해 구체적으로 알지 못하더라도 런타임에 접근하게 해주는 기능입니다.

Reflection allows programmatic access to information about the fields, methods and constructors of loaded classes, and the use of reflected fields, methods, and constructors to operate on their underlying counterparts, within encapsulation and security restrictions.
리플렉션을 사용하면 로드된 클래스의 필드, 메서드 및 생성자에 대한 정보에 programmatic하게 접근할 수 있으며, 캡슐화 및 보안 제한 내에서 기본 대응물에서 작동하기 위해 반사된 필드, 메서드 및 생성자를 사용할 수 있습니다.
- Oracle docs

 

Class<T>는 public한 생성자가 없어 임의로 없습니다. 하지만 JVM이 모든 클래스들을 로드한 뒤 클래스 로더의 defineClass를 호출해 만들어집니다.

Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.
클래스에 public 생성자가 없습니다. 대신 Class 객체는 JVM에 의해 클래스들이 로드될 때 클래스 로더의 defineClass 메소드 호출에 의해 자동으로 생성됩니다.
- Oracle docs

이렇게 만들어진 Class<T> 객체는 세가지 방법으로 얻어올 수 있습니다.

  • SomeType.class
  • someInstance.getClass()
  • Class.forName("{Fully Qualified Class Name}")

 

 

활용

이렇게 얻은 class는 다음과 같이 활용할 수 있습니다.

class Book {
    private final String name;
    
    public Book(String name) {
        this.name = name;
    }

    private void read(int page) {
        System.out.println("read " + page);
    }
}


Class<Book> bookClass = Book.class;

//String 타입을 인자로 받는 생성자에 접근
Constructor<Book> constructor = bookClass.getConstructor(String.class);

Book book = constructor.newInstance("Java Reflection");

//read라는 이름의 int 타입을 인자로 받는 함수에 접근
Method method = bookClass.getDeclaredMethod("read", int.class);

//private 접근 제한을 해제
method.setAccessible(true);

method.invoke(book, 200); // read 200

 

 

이런 Reflection은 아주 다양한 곳에서 사용되고 있습니다. 그 중 대표적인 것은 Spring의 DI Container가 있습니다. Reflection은 클래스, 생성자, 함수, 필드 뿐만 아니라 어노테이션, enum, 인터페이스 등에도 접근이 가능한데, 특정 어노테이션이 붙은 클래스 혹은 필드를 찾아 의존성을 주입해주는 것입니다.

 

 

주의점

Reflection은 너무나 강력한 기능이지만 마구잡이로 사용해선 안됩니다. Reflection을 사용할 경우 발생할 수 있는 단점 혹은 주의해야 할 점들이 있습니다.

  • 성능 : Reflection은 정적타입 언어인 Java의 타입들을 동적으로 접근하고, 수정 및 사용할 수 있도록 해줍니다. 하지만 이 때문에 JVM의 성능최적화가 동작하지 않습니다.
  • 유지보수성 : Reflection은 런타임시에 클래스 등에 접근하기 때문에 발생 가능한 문제들을 컴파일 타임에 알 수 없습니다. 또한 접근 지시자를 무시할 수 있어 이 또한 발견하기 어려운 문제들을 만들어 낼 수 있습니다.

 

 

 

ref.

Oracle docs - java.lang.reflect

Oracle docs - Class<T>

Oracle Java tutorial - Reflection API

더 자바, 코드를 조작하는 다양한 방법

 

'java' 카테고리의 다른 글

[Java] Lambda Expression  (0) 2021.11.08
[Java] Generics  (0) 2021.10.29
[Java] Exception Handling  (0) 2021.10.27
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함