관리 메뉴

피터의 개발이야기

[Java] 리플렉션 (reflection) 개념 이해하기 본문

Programming/JAVA

[Java] 리플렉션 (reflection) 개념 이해하기

기록하는 백앤드개발자 2024. 8. 13. 10:10
반응형

ㅁ 들어가며

ㅇ 리플렉션(Reflection)은 자바 프로그래밍 언어에서 실행 중인 프로그램이 자신의 구조를 검사하고 수정할 수 있는 기능이다.

ㅇ 이를 통해 클래스, 인터페이스, 필드, 메서드 등의 정보를 런타임에 동적으로 접근하고 조작할 수 있다.

ㅇ 리플렉션은 주로 컴파일 시점에 알 수 없는 객체를 다룰 때 유용하게 사용된다.

 

ㅁ 리플렉션의 주요 기능

필드 접근하기

class Person {
var name: String? = null
    var age: Int? = null
    constructor()  // 기본 생성자

    constructor(name: String) {
        this.name = name
    }

    constructor(age: Int) {
        this.age = age
    }
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
}

fun main() {
    val clazz = Person::class.java
    val fields = clazz.declaredFields
    for (field in fields) {
        println(field.name)
    }
}

# 결과
name
address
age
email

 클래스의 필드에 접근하여 값을 읽거나 쓸 수 있다.

ㅇ Jackson, hibernate는 리플렉션을 사용하고 있다.

 

ObjectMapper objectMapper = new ObjectMapper();
try {
    String result = objectMapper.writeValueAsString(new Person("캠핑패카", 20));
    System.out.println(result);
} catch (JsonProcessingException e) {
    e.printStackTrace();
}

ㅇ 객체를 json 타입으로 변경해 주는 jackson 라이브러리의 ObjectMapper이 대표적 사용사례이다.

ㅇ 이 코드를 실행하려면 jackson-module-kotlin 의존성을 프로젝트에 추가해야 한다.

 

 

인스턴스 생성

class Person {
var name: String? = null
    var age: Int? = null
    constructor()  // 기본 생성자

    constructor(name: String) {
        this.name = name
    }

    constructor(age: Int) {
        this.age = age
    }
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
}

fun main() {
    val clazz = Person::class.java
    try {
        val constructor = clazz.getConstructor(String::class.java, Int::class.java)
        val newPerson = constructor.newInstance("캠핑패카", 20)
        println(newPerson)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

ㅇ 클래스의 생성자를 이용하여 인스턴스를 동적으로 생성할 수 있다.

 

ㅇ 위의 코드를 실행하고 생성된 인스턴스를 디버깅 모드로 살펴보았다.

 

메서드 호출

public class Person {
    private String name;
    private int age;

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

    @Override
    public String toString() {
        return "이름 : " + this.name + ", 나이 : " + age;
    }
}

fun main() {
    val clazz = Person::class.java
    try {
        val constructor = clazz.getConstructor(String::class.java, Int::class.java)
        val newPerson = constructor.newInstance("캠핑패카", 20)
        val toStringMethod = newPerson::class.java.getMethod("toString")
        val result = toStringMethod.invoke(newPerson) as String
        println(result)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

/**
이름 : 캠핑패카, 나이 : 20
*/

ㅇ 클래스의 메서드를 동적으로 호출할 수 있다.

 

클래스 정보 조회

ㅇ 클래스 타입을 이용하여 클래스의 메타데이터를 조회할 수 있다.

ㅇ 클래스의 메서드, 생성자 정보, 필드 값 변경, 배열 사용의 예제를 확인할 수 있다.

ㅇ 관련 블로그:

   ㄴ Java Reflection API 사용법 - Oracle

   ㄴ Java Reflection 사용법 - Baeldung

 

ㅁ 리플렉션의 활용 예

프레임워크 개발

 ㄴ Spring, Hibernate 등 많은 프레임워크가 리플렉션을 사용하여 동적으로 객체를 생성하고, 메서드를 호출하며, 필드에 접근한다.
라이브러리 개발

 ㄴ Jackson, Gson 같은 JSON 파서 라이브러리도 리플렉션을 사용하여 객체를 JSON으로 변환하거나 JSON을 객체로 변환한다.
디버깅 및 테스트

 ㄴ 리플렉션을 사용하여 테스트 중에 객체의 내부 상태를 검사하거나, 비공개 메서드를 호출할 수 있다.

 

ㅁ 마무리

리플렉션은 자바 언어의 중요한 기능 중 하나로, 동적인 프로그래밍을 가능하게 한다. 이를 잘 활용하면 더 유연하고 강력한 애플리케이션을 작성할 수 있다.

 

ㅁ 함께 보면 좋은 사이트

[Java] 리플렉션 (reflection) 개념 이해하기

Java Reflection 사용법 - Baeldung
Java Reflection API 사용법 - Oracle

 

반응형
Comments