메타 프로그래밍 리플렉션(Reflection)이란?

2025. 3. 12. 16:54개발/개념 및 기법

728x90
반응형

1. 리플렉션(Reflection)이란?

리플렉션은 앱 실행 중에 클래스, 메서드, 속성 등의 정보를 동적으로 가져오거나 수정할 수 있는 기능이다.

즉, 코드가 자기 자신을 들여다보고 조작하는 능력.

(1) 리플렉션이 필요한 이유

  • 런타임에서 클래스 정보를 조회해야 할 때 → 예를 들어, DI(의존성 주입) 같은 곳에서 객체 타입을 몰라도 생성해야 할 경우
  • 코드 수정 없이 동적으로 메서드 호출 → 프레임워크에서 코드를 직접 수정하지 않고 기능을 확장할 때
  • JSON 직렬화/역직렬화 → Gson, Moshi 같은 라이브러리가 리플렉션을 사용해서 객체를 변환

(2) 리플렉션 사용 예제

  • 클래스 정보를 가져오기
import kotlin.reflect.full.*

data class User(val name: String, val age: Int)

fun main() {
    val kClass = User::class // 클래스 정보 가져오기
    println("클래스 이름: ${kClass.simpleName}")

    val properties = kClass.memberProperties
    println("프로퍼티 목록: $properties")
}
  • 동적으로 프로퍼티 값 가져오기
import kotlin.reflect.full.memberProperties

data class Person(val name: String, val age: Int)

fun main() {
    val person = Person("형님", 30)
    val kClass = person::class

    val nameProperty = kClass.memberProperties.find { it.name == "name" }
    println("name 프로퍼티 값: ${nameProperty?.getter?.call(person)}")
}
  • 동적으로 메서드 호출하기
import kotlin.reflect.full.functions

class Hello {
    fun greet() = "안녕하세요, 형님!"
}

fun main() {
    val hello = Hello()
    val kClass = hello::class

    val greetMethod = kClass.functions.find { it.name == "greet" }
    println("메서드 호출 결과: ${greetMethod?.call(hello)}")
}

2. 리플렉션을 지원하는 언어

리플렉션(Reflection)은 모든 프로그래밍 언어에서 존재하는 건 아니다.

동적 타입이나 메타 프로그래밍이 지원되는 언어들에 한해서만 사용 가능하다.

(1) 리플렉션이 지원되는 대표적인 언어

  • Kotlin - kotlin.reflect 패키지 사용
  • Java - java.lang.reflect 패키지 사용
  • Python - getattr(), type(), dir() 등으로 접근 가능
  • C# - .NET에서 System.Reflection 사용
  • Ruby - Object#methods, Object#instance_variables 등 활용 가능
  • JavaScript - Object.keys(), Reflect API 등 사용
  • Swift - Mirror API 활용 가능

이런 언어들은 런타임에서 클래스, 메서드, 속성 등을 확인하고 동적으로 조작할 수 있는 기능을 제공!!!

(2) 리플렉션이 지원되지 않거나 제한적인 언어

  • C, C++ - 컴파일 타임에 구조가 고정되기 때문에 리플렉션 기능 없음
  • Rust - 성능과 안전성 때문에 기본적으로 지원하지 않음 (serde 같은 라이브러리는 있음)
  • Go - reflect 패키지가 있지만 타입 정보만 확인 가능 (메타프로그래밍 수준은 낮음)

이런 언어들은 정적으로 타입이 결정되며, 실행 중에 구조를 변경하는 기능이 거의 없음


3. 리플렉션 사용 시 주의할 점

(1) 성능 저하

리플렉션은 정적 코드보다 느리기 떄문에 앱의 성능이 중요한 곳에서는 자제해야 한다.

(2) 안드로이드 ProGuard 최적화 문제

난독화 설정 시 리플렉션을 사용하면 클래스 이름이 변경될 수 있어 문제가 발생한다.

(3) 보안 이슈

런타임에서 동적으로 클래스와 메서드를 호출하기 때문에 잘못된 접근이 발생할 가능성이 있다.


4. 리플렉션을 사용하는 이유

위와 같이 성능 저하와 복잡성 증가의 단점에도 불구하고 사용하는 이유는 무엇일까?

(1) 컴파일 타임에 알 수 없는 클래스를 다룰 때

예를 들어, 플러그인 시스템, DI(의존성 주입) 등에서 런타임에 동적으로 객체를 생성해야 하는 경우 사용한다.

(2) JSON → 객체 변환 (직렬화 & 역직렬화)

데이터를 네트워크에서 받아와야 하는데, 클래스를 미리 정의할 수 없는 경우,

Gson, Moshi 같은 JSON 파싱 라이브러리들이 리플렉션을 활용한다.

(3) 동적으로 메서드를 호출해야 할 때

특정 클래스에 어떤 메서드가 있는지 모르는 상황에서, 메서드 이름을 문자열로 받아 실행해야 할 때

리플렉션이 없으면 switch-case 같은 하드코딩을 해야 한다.

(4) 코드 수정 없이 확장성을 높일 때

플러그인 시스템, ORM 프레임워크, 동적 바인딩 같은 기능을 구현할 때 사용한다.

예를 들어, Room Database에서 @Entity 클래스를 자동으로 분석하는 기능도 리플렉션을 활용


리플렉션은 런타임에 클래스나 메서드를 동적으로 다룰 때 필수적인 기능이다.

하지만 성능 저하, 보안 이슈가 있어 남발하면 안된다.

 

728x90
반응형