Меня немного смущает различие между getFields
методом и getDeclaredFields
методом при использовании отражения Java.
Я прочитал, что getDeclaredFields
дает вам доступ ко всем полям класса и getFields
возвращает только открытые поля. Если это так, почему бы вам просто не использовать всегда getDeclaredFields
?
Может ли кто-нибудь подробно рассказать об этом и объяснить разницу между этими двумя методами, а также то, когда и почему вы хотите использовать один метод над другим?
java
reflection
BlackHatSamurai
источник
источник
getField
может получить поле, унаследованное от суперкласса, ноgetDeclaredField
не может.getDeclaredField
ограничьте себя классом, для которого вы вызываете функцию.getField
не может получить доступ к частным пользователямОтветы:
GetFields ()
Все
public
поля по всей иерархии классов.getDeclaredFields ()
Все поля, независимо от их доступности, но только для текущего класса, а не базовые классы, от которых текущий класс может наследовать.
Чтобы получить все поля в иерархии, я написал следующую функцию:
exclusiveParent
Класс предусмотрен для предотвращения извлечения полей изObject
. Это может быть,null
если вы хотитеObject
поля.Чтобы уточнить,
Lists.newArrayList
приходит из Гуавы.Обновить
К вашему сведению, приведенный выше код опубликован на GitHub в моем проекте LibEx в ReflectionUtils .
источник
Field#get
и аналогичными методами. Другими словами, этот подход не разрешает текущему классу доступ к закрытому интерфейсу его суперкласса, как это делает типичная компиляция.setAccessible
и нет Менеджера безопасности на местеprivate
полям можно получить доступ только черезgetDeclaredFields
который зависит от класса. Каждое поле (даже с одинаковым типом и именем) будет отдельнымField
экземпляром.Как уже упоминалось,
Class.getDeclaredField(String)
смотрит только на те поля, изClass
которых вы его называете.Если вы хотите найти
Field
вClass
иерархии, вы можете использовать эту простую функцию:Это полезно, например, для поиска
private
поля в суперклассе. Кроме того, если вы хотите изменить его значение, вы можете использовать его следующим образом:источник
try try { field = clazz.getDeclaredField(name); } catch (NoSuchFieldException e) { clazz = clazz.getSuperclass(); if(clazz==null){ throw e; } }
public Field[] getFields() throws SecurityException
Возвращает массив, содержащий объекты Field, отражающие все доступные публичные поля класса или интерфейса, представленные этим объектом Class. Элементы в возвращаемом массиве не сортируются и не располагаются в каком-либо определенном порядке. Этот метод возвращает массив длины 0, если у класса или интерфейса нет доступных открытых полей или если он представляет класс массива, примитивный тип или void.
В частности, если этот объект Class представляет класс, этот метод возвращает открытые поля этого класса и всех его суперклассов. Если этот объект Class представляет интерфейс, этот метод возвращает поля этого интерфейса и всех его суперинтерфейсов.
Поле неявной длины для класса массива не отражается этим методом. Пользовательский код должен использовать методы класса Array для манипулирования массивами.
public Field[] getDeclaredFields() throws SecurityException
Возвращает массив объектов Field, отражающих все поля, объявленные классом или интерфейсом, представленным этим объектом Class. Это включает в себя открытые, защищенные, доступ по умолчанию (пакет) и частные поля, но исключает унаследованные поля. Элементы в возвращаемом массиве не сортируются и не располагаются в каком-либо определенном порядке. Этот метод возвращает массив длины 0, если класс или интерфейс не объявляет полей, или если этот объект Class представляет примитивный тип, класс массива или void.
А что если мне понадобятся все поля из всех родительских классов? Необходим некоторый код, например, с https://stackoverflow.com/a/35103361/755804 :
источник
Из учебников Java Reflection :
источник