Programing

Java 리플렉션에서 getFields와 getDeclaredFields의 차이점은 무엇입니까?

lottogame 2020. 5. 27. 07:31
반응형

Java 리플렉션에서 getFields와 getDeclaredFields의 차이점은 무엇입니까?


Java 리플렉션을 사용할 때 getFields메소드와 메소드 의 차이점에 대해 약간 혼란 스럽습니다 getDeclaredFields.

나는 getDeclaredFields클래스의 모든 필드에 액세스 할 수 있고 getFields공개 필드 만 반환 한다는 것을 읽었습니다 . 이 경우 항상 왜 항상 사용하지 getDeclaredFields않습니까?

누군가 이것에 대해 자세히 설명하고 두 방법의 차이점과 언제 어떻게 다른 것을 사용하고 싶습니까?


getFields ()

모든 public필드는 전체 클래스 계층 구조입니다.

getDeclaredFields ()

현재 클래스가 상속 할 수있는 기본 클래스가 아닌 액세스 가능성에 관계없이 현재 클래스에 대해서만 모든 필드.

모든 필드를 계층 구조로 가져 오기 위해 다음 함수를 작성했습니다.

public static Iterable<Field> getFieldsUpTo(@Nonnull Class<?> startClass, 
                                   @Nullable Class<?> exclusiveParent) {

   List<Field> currentClassFields = Lists.newArrayList(startClass.getDeclaredFields());
   Class<?> parentClass = startClass.getSuperclass();

   if (parentClass != null && 
          (exclusiveParent == null || !(parentClass.equals(exclusiveParent)))) {
     List<Field> parentClassFields = 
         (List<Field>) getFieldsUpTo(parentClass, exclusiveParent);
     currentClassFields.addAll(parentClassFields);
   }

   return currentClassFields;
}

exclusiveParent필드는 필드 검색을 방지하기 위해 제공됩니다 Object. 그것은있을 수 있습니다 null당신이 원하는 경우 Object필드를.

명확히하기 위해 Lists.newArrayList구아바 에서 온다.

최신 정보

참고로, 위 코드는 ReflectionUtils의 LibEx 프로젝트에서 GitHub에 게시되었습니다 .


이미 언급했듯이, Class.getDeclaredField(String)필드 Class를 호출 한 필드 만 봅니다 .

계층 구조 Field에서 a를 검색 Class하려면 다음과 같은 간단한 기능을 사용할 수 있습니다.

/**
 * Returns the first {@link Field} in the hierarchy for the specified name
 */
public static Field getField(Class<?> clazz, String name) {
    Field field = null;
    while (clazz != null && field == null) {
        try {
            field = clazz.getDeclaredField(name);
        } catch (Exception e) {
        }
        clazz = clazz.getSuperclass();
    }
    return field;
}

private예를 들어 수퍼 클래스에서 필드 를 찾는 데 유용합니다 . 또한 값을 수정하려면 다음과 같이 사용할 수 있습니다.

/**
 * Sets {@code value} to the first {@link Field} in the {@code object} hierarchy, for the specified name
 */
public static void setField(Object object, String fieldName, Object value) throws Exception {
    Field field = getField(object.getClass(), fieldName);
    field.setAccessible(true);
    field.set(object, value);
}

public Field[] getFields() throws SecurityException

Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object. The elements in the array returned are not sorted and are not in any particular order. This method returns an array of length 0 if the class or interface has no accessible public fields, or if it represents an array class, a primitive type, or void.

Specifically, if this Class object represents a class, this method returns the public fields of this class and of all its superclasses. If this Class object represents an interface, this method returns the fields of this interface and of all its superinterfaces.

The implicit length field for array class is not reflected by this method. User code should use the methods of class Array to manipulate arrays.


public Field[] getDeclaredFields() throws SecurityException

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields. The elements in the array returned are not sorted and are not in any particular order. This method returns an array of length 0 if the class or interface declares no fields, or if this Class object represents a primitive type, an array class, or void.


And what if I need all fields from all parent classes? Some code is needed, e.g. from https://stackoverflow.com/a/35103361/755804:

public static List<Field> getAllModelFields(Class aClass) {
    List<Field> fields = new ArrayList<>();
    do {
        Collections.addAll(fields, aClass.getDeclaredFields());
        aClass = aClass.getSuperclass();
    } while (aClass != null);
    return fields;
}

From Java Reflection tutorials:

enter image description here

참고URL : https://stackoverflow.com/questions/16966629/what-is-the-difference-between-getfields-and-getdeclaredfields-in-java-reflectio

반응형