본문 바로가기
(2024-10) 스파르타 내일배움캠프 - 백엔드/Java Reflect

Field 제어

by 어뫄어뫄 2024. 11. 27.
import java.lang.reflect.Field;

public class ReflectionDemo {

    public static void main(String[] args) {
        try {
            // Person 객체 생성
            Person person = new Person("John Doe", 30);

            // Person 클래스의 필드 정보 출력
            printClassFieldsInfo(person);

            // 'age' 필드의 값을 변경
            setFieldValue(person, "age", 35);

            // 변경된 필드 값 출력
            System.out.println("Updated Person: " + person);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 클래스의 모든 필드 정보를 출력하는 메서드
    public static void printClassFieldsInfo(Object obj) {
        Class<?> clazz = obj.getClass();
        System.out.println("Class Name: " + clazz.getName());
        
        // 모든 필드 가져오기
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true); // private 필드 접근 허용
            try {
                System.out.println(String.format("Field Name: %s, Type: %s, Value: %s",
                        field.getName(),
                        field.getType().getName(),
                        field.get(obj))); // 필드 값을 가져옴
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    // 지정된 필드의 값을 변경하는 메서드
    public static void setFieldValue(Object obj, String fieldName, Object value) {
        try {
            Class<?> clazz = obj.getClass();
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true); // private 필드 접근 허용
            field.set(obj, value); // 필드에 새로운 값 설정
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    // Person 클래스 정의
    public static 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 "Person{name='" + name + '\'' + ", age=" + age + '}';
        }
    }
}
  • getDeclaredField(String name)
    • 설명: 지정된 이름의 필드를 가져옵니다. 이 메서드는 해당 클래스에 선언된 필드 중에서 접근 제어자(public, private 등과 관계없이)를 고려하지 않고 찾습니다.
    • 용법:
    • Field minPriceStaticField = Movie.class.getDeclaredField("MINIMUM_PRICE");
       
  • getDeclaredFields()
    • 설명: 해당 클래스에 선언된 모든 필드를 배열 형태로 반환합니다. 반환되는 필드는 접근 제어자와 상관없이 포함됩니다.
    • 용법:
    • for (Field field : clazz.getDeclaredFields()) {
  • getName()
    • 설명: 필드의 이름을 반환합니다. Field 객체에서 호출할 수 있습니다.
    • 용법:
    • field.getName()
       
  • getType()
    • 설명: 필드의 데이터 타입을 반환합니다. Field 객체에서 호출할 수 있으며, 반환된 Class 객체에서 getName() 메서드를 통해 타입 이름을 가져올 수 있습니다.
    • 용법:
    • field.getType().getName()
       
  • isSynthetic()
    • 설명: 필드가 합성 필드인지 여부를 확인합니다. 합성 필드는 주로 컴파일러에 의해 생성된 필드로, 일반적으로 개발자가 직접 생성한 필드가 아닙니다.
    • 용법:
    • field.isSynthetic()
       
  • get(Object obj)
    • 설명: 주어진 객체에서 필드의 값을 가져옵니다. 해당 필드가 static인 경우 null을 전달하여 호출할 수 있습니다.
    • 용법:
    • field.get(instance)