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;
}