Java를 사용하다 보면 클래스의 필드 값에 동적으로 접근하거나, 필드의 데이터 타입을 알아내야 할 때가 있습니다. 이럴 때 유용하게 사용할 수 있는 것이 바로 Reflection인데요. 오늘은 간단한 예시를 통해, Reflection을 이용해 클래스 필드에 접근하고, 데이터 타입을 확인하는 방법을 설명드리겠습니다.
Reflection을 활용한 필드 접근 및 데이터 타입 확인
1. Reflection으로 필드 값에 접근하기
클래스에서 선언된 필드 값을 가져올때는 getter 메서드를 통해 가져옵니다. 하지만 경우에 따라서 허용여부와 관계없이 필드 이름 리스트를 받아오거나 private으로 선언된 필드명을 가져와야할 때가 있는데요. 이 경우에는 Reflection을 통해 필드 정보들을 가져올 수 있습니다.
여기에서는 User 클래스를 예시로 들어, Reflection을 통해 비공개 필드에 어떻게 접근하고, 값을 가져오는지 설명해 드리겠습니다.
class User {
private String username;
private String email;
private int age;
public User(String username, String email, int age) {
this.username = username;
this.email = email;
this.age = age;
}
}
User 클래스에 선언된 모든 필드는 private으로 선언되어 있습니다.
2. Class 객체를 통해 클래스 정보에 접근 (Method Area)
// User 클래스의 필드에 접근하는 예시
User user = new User("admin", "admin@example.com", 30);
List<Field> userFields = new ArrayList<>(Arrays.asList(User.class.getDeclaredFields()));
대상 클래스에 선언된 필드 배열을 가져옵니다. 값들을 꺼내오기 쉽도록 리스트로 변환합니다.
Reflection의 핵심은 Class 객체를 사용해 런타임에 클래스의 메타데이터(클래스가 가진 필드, 메서드, 생성자 등)에 접근할 수 있다는 점 입니다. 위 코드에서는 User 클래스 정보에서 필드 정보를 가져와 Field 클래스 배열에 저장된 값을 반환받습니다.
Reflection을 사용하게 되면 위 과정은 컴파일 타임이 아닌 런타임에 일어나기 때문에, User 클래스의 필드 정보를 동적으로 가져올 수 있게 됩니다.
3. 클래스 정보를 이용해 메모리에서 저장된 값 읽어오기 (Heap)
for (Field field : userFields) {
try {
// 비공개 필드에도 접근 가능하도록 설정
field.setAccessible(true);
// 필드 이름과 값을 가져옴
String fieldName = field.getName();
Object fieldValue = field.get(user);
System.out.println("필드 이름: " + fieldName + ", 필드 값: " + fieldValue);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
비공개 필드에도 접근이 가능하도록 설정을 변환합니다.
기본적으로 Java에서는 private 제어자를 사용한 필드는 외부에서 직접 접근할 수 없습니다. 하지만 Reflection을 사용하면 setAccessible(true)를 통해 private 필드에도 접근할 수 있게 만들어 줍니다.
이 메서드는 일반적으로 보안적인 이유로 숨겨져 있는 필드나 메서드에 접근할 때 사용되며, 이 또한 Reflection의 기능 중 하나입니다. 정리하면, Reflection은 클래스의 캡슐화를 무시하고 직접적으로 필드에 접근할 수 있는 방법을 제공합니다.
Object fieldValue = field.get(user);
Field 객체를 통해 user 객체의 특정 필드 값을 가져옵니다. 이 과정도 컴파일 타임이 아닌 런타임 시에 동적으로 필드 값을 가져오게 됩니다.
여기서 주목할 부분은 Reflection을 사용하면 필드의 이름이나 타입을 사전에 몰라도, 런타임 시에 클래스의 정보를 활용해 그 값을 가져올 수 있다는 것입니다. 즉, 컴파일 시점에는 어떤 필드가 있는지 몰라도, 프로그램이 실행될 때 해당 객체의 필드 값을 읽어올 수 있습니다.
마무리
오늘은 Java의 Reflection을 활용해 클래스의 비공개 필드에 접근하고 데이터를 읽어오는 방법을 살펴봤습니다. Reflection은 동적으로 클래스의 메타데이터에 접근할 수 있는 매우 유용한 기능입니다.
하지만 사용시 고려해야할 주의사항으로는 성능이슈를 고려해야한다는 부분입니다. Reflection을 통해 필드나 메서드에 접근하면, JVM이 런타임에 메타데이터 테이블을 조회하고 추가적인 검증 작업을 수행해야 합니다. 또한, 메모리 상에서 필드의 위치를 찾아내는 작업은 일반적인 방법보다는 당연히 비용이 많이 들기 때문에 성능 저하가 발생합니다. 이런 이유로 Reflection을 반복적으로 사용하면 애플리케이션의 성능에 악영향을 미칠 수 있으니, 꼭 필요한 경우에만 사용하는 것이 좋습니다.
궁금한 점이 있으시면 댓글로 남겨 주세요. 감사합니다.
'Skills (스터디) > Java' 카테고리의 다른 글
[Java] Reflection 기본개념 및 동작원리 (0) | 2024.09.15 |
---|---|
[JAVA] Thread 기본개념 - 선언방법 2가지 예시코드와 특징비교 (0) | 2023.04.09 |
[Java] parallelStream() 메서드 사용시 예상되는 문제점 및 해결방안 [2] (0) | 2023.02.26 |
[Java] parallelStream() 메서드 사용시 예상되는 문제점 및 해결방안 [1] (0) | 2023.02.26 |
[Maven] 간단한 Multi-Module 프로젝트 만들기 (0) | 2023.02.11 |
최근댓글