본문 바로가기

Programming!

뜬금 Reflection 으로 field 받아오기.

getFields와 getDeclaredFields 의 차이는 넘어가고..

---

 

플젝도중 누군가 jpa 엔티티의 id를 빼오는 작업을 하는데 해당 작업의 구현시.. 다른 누군가가 만들어둔 유틸성 클래스를 사용하더라.

근데 id가 정상적으로 처리되지 않더라고 한다. ( 아마 ID가 들어있는 class를 extends하는 방식이라 그런거 같다고.. - AbcEntity extends JpaIdBase 뭐 이런식..)

 

해서 그 누군가가 만들어둔 유틸 클래스를 디컴파일해서 보니 역시나...  Arguments 클래스에 getDeclaredFields 를 이용하여 field값들을 처리하더라.

그럼 역시 super class의 field를 볼 수 없는건 당연하겠지. ( 고치면 좋을 듯 한데 유틸 클래스 작성자의 의도를 모르니 넘어가자. )

 

여튼 매우 기초적인 부분이지만 관련 테스트를 만들어 봄.

 

 

@Slf4j
public class SuperClassFiledTest {

    @Test
    @DisplayName("자기자신의 속성 필드를 조회한다. ")
    public void test_a(){
        Field[] fields = Employee.class.getDeclaredFields();
        Arrays.stream(fields).forEach(o->log.info("Field : {}", o.getName()));
        Field field = Arrays.stream(fields).findFirst().orElseThrow(()->new NullPointerException("Field를 찾을 수 없습니다."));
        assertEquals(field.getName(), "name");
    }

    @Test
    @DisplayName("자신의 부모속성 필드를 조회한다. ")
    public void test_b(){
        Field[] fields = Employee.class.getSuperclass().getDeclaredFields();
        Arrays.stream(fields).forEach(o->log.info("Field : {}", o.getName()));
    }

    @Test
    @DisplayName("자기자신 필드와 부모속성 필드를 조회한다. ")
    public void test_c(){
        List<Field> results = new ArrayList<>();
        Class<?> clz = Employee.class;
        while (clz != null && clz != Object.class) {
            Collections.addAll(results, clz.getDeclaredFields());
            clz = clz.getSuperclass();
        }
        results.forEach(o->log.info("Field : {}", o.getName()));

    }

    @Test
    @DisplayName("그냥 리플렉션 유틸을 써라.")
    @SuppressWarnings("unchecked")
    public void test_d(){
        Set<Field> fields = ReflectionUtils.getAllFields(Employee.class);
        fields.forEach(o->log.info("Field : {}", o.getName()));
    }
}
@Getter
@Setter
public class Employee extends Human{

    private String name;

    private String nickName;
}

@Getter
@Setter
public abstract class Human {
    private String genderSymbol;
}