Jaka jest różnica między getFields i getDeclaredFields w Javie
Jestem trochę zdezorientowany co do różnicy między metodą getFields
a metodą getDeclaredFields
przy użyciu Java reflection.
Czytałem, że getDeclaredFields
daje dostęp do wszystkich pól klasy i że getFields
zwraca tylko pola publiczne. Jeśli tak jest, dlaczego nie zawsze używasz getDeclaredFields
?
Czy ktoś mógłby to rozwinąć i wyjaśnić różnicę między tymi dwiema metodami i kiedy / dlaczego chciałbyś użyć jednej nad drugą?
3 answers
Wszystkie public
Pola w całej hierarchii klas.
Wszystkie pola, niezależnie od ich dostępności, ale tylko dla bieżącej klasy, a nie żadnych klas bazowych, od których obecna klasa może być dziedziczona.
Aby uzyskać wszystkie pola w hierarchii, napisałem następującą funkcję:
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;
}
Klasa exclusiveParent
jest zapewniona, aby zapobiec pobieraniu pól z Object
. Może to być null
, Jeśli chcesz pola Object
.
Dla wyjaśnienia, Lists.newArrayList
pochodzi z guawy.
Update
FYI, powyższy kod jest opublikowany na Githubie w moim projekcie LibEx W ReflectionUtils .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-15 06:08:07
Jak już wspomniano, Class.getDeclaredField(String)
patrzy tylko na pola z Class
, w których je wywołujesz.
Jeśli chcesz wyszukać Field
w hierarchii Class
, możesz użyć tej prostej funkcji:
/**
* 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;
}
Jest to przydatne, aby znaleźć pole private
z klasy nadrzędnej, na przykład. Ponadto, jeśli chcesz zmodyfikować jego wartość, możesz użyć go w następujący sposób:
/**
* 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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-19 20:15:17
public Field[] getFields() throws SecurityException
Zwraca tablicę zawierającą Obiekty pola odzwierciedlające wszystkie Dostępne pola publiczne klasy lub interfejsu reprezentowanego przez ten obiekt klasy. Zwracane elementy tablicy nie są sortowane i nie są w żadnej określonej kolejności. Metoda zwraca tablicę o długości 0, jeśli klasa lub interfejs nie ma dostępnych publicznych pól, lub jeśli reprezentuje klasę tablicy, Typ prymitywny lub void.
W szczególności, jeśli obiekt tej klasy reprezentuje klasy, ta metoda zwraca publiczne pola tej klasy i wszystkich jej superklas. Jeśli obiekt tej klasy reprezentuje interfejs, metoda ta zwraca pola tego interfejsu i wszystkich jego superinterfejsów.
Domyślne pole długości dla klasy array nie jest odzwierciedlane przez tę metodę. Kod użytkownika powinien używać metod tablicy klas do manipulowania tablicami.
public Field[] getDeclaredFields() throws SecurityException
Zwraca tablicę obiektów pola odzwierciedlającą wszystkie pola zadeklarowane przez klasę lub interfejs reprezentowany przez ten obiekt klasy. To obejmuje publiczny, chroniony, domyślny (pakiet) dostęp i prywatny pola, ale nie obejmuje dziedziczenia pola. Zwracane elementy tablicy nie są sortowane i nie są w żadnej określonej kolejności. Metoda ta zwraca tablicę o długości 0, jeśli klasa lub interfejs nie deklaruje żadnych pól, lub jeśli obiekt tej klasy reprezentuje typ prymitywny, klasę tablicy lub pustka.
A co jeśli potrzebuję wszystkich pól ze wszystkich klas nadrzędnych? Potrzebny jest jakiś kod, np. z 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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:13