Jestem trochę zdezorientowany co do różnicy między getFields
metodą agetDeclaredFields
metodą przy użyciu odbicie Java.
Przeczytałem, że getDeclaredFields
daje ci dostęp do wszystkich pól klasy i getFields
zwraca tylko pola publiczne. Jeśli tak jest, dlaczego po prostu nie zawsze używałbyś getDeclaredFields
?
Czy ktoś może rozwinąć tę kwestię i wyjaśnić różnicę między tymi dwiema metodami oraz kiedy / dlaczego miałbyś chcieć używać jednej z nich?
java
reflection
BlackHatSamurai
źródło
źródło
getField
może uzyskać pole dziedziczone z nadklasy, alegetDeclaredField
nie może.getDeclaredField
ogranicz się do klasy, na której wywołujesz funkcję.getField
nie może uzyskać dostępu do członków prywatnychOdpowiedzi:
getFields ()
Wszystkie
public
pola w górę całej hierarchii klas.getDeclaredFields ()
Wszystkie pola, niezależnie od ich dostępności, ale tylko dla bieżącej klasy, nie żadnych klas podstawowych, z których może dziedziczyć bieżąca klasa.
Aby przenieść wszystkie pola w górę hierarchii, napisałem następującą funkcję:
Ta
exclusiveParent
klasa ma zapobiegać pobieraniu pól zObject
. Może tak być,null
jeśli chceszObject
pola.Aby wyjaśnić,
Lists.newArrayList
pochodzi z Guawy.Aktualizacja
Do Twojej wiadomości, powyższy kod został opublikowany na GitHub w moim projekcie LibEx w ReflectionUtils .
źródło
Field#get
i podobnych metod. Innymi słowy, to podejście nie pozwala bieżącej klasie na dostęp do prywatnego interfejsu jego nadklasy, podobnie jak typowa kompilacja.setAccessible
i nie ma menedżera zabezpieczeńprivate
pola są dostępne tylko za pośrednictwem,getDeclaredFields
które są specyficzne dla klasy. Każde pole (nawet o tym samym typie i nazwie) byłoby odrębnymField
wystąpieniem.Jak już wspomniano,
Class.getDeclaredField(String)
patrzy tylko na pola zClass
w którym je wywołujesz.Jeśli chcesz wyszukać
Field
wClass
hierarchii, możesz użyć tej prostej funkcji:Jest to przydatne na przykład do znalezienia
private
pola z nadklasy. Ponadto, jeśli chcesz zmodyfikować jego wartość, możesz użyć jej w następujący sposób:źródło
try try { field = clazz.getDeclaredField(name); } catch (NoSuchFieldException e) { clazz = clazz.getSuperclass(); if(clazz==null){ throw e; } }
public Field[] getFields() throws SecurityException
Zwraca tablicę zawierającą obiekty Field odzwierciedlające wszystkie dostępne pola publiczne klasy lub interfejs reprezentowany przez ten obiekt Class. Zwracane elementy tablicy nie są sortowane i nie mają określonej kolejności. Ta metoda zwraca tablicę o długości 0, jeśli klasa lub interfejs nie ma dostępnych pól publicznych lub jeśli reprezentuje klasę tablicy, typ pierwotny lub void.
W szczególności, jeśli ten obiekt klasy reprezentuje klasę, ta metoda zwraca pola publiczne tej klasy i wszystkich jej nadklas. Jeśli ten obiekt klasy reprezentuje interfejs, ta metoda zwraca pola tego interfejsu i wszystkich jego super interfejsów.
Ta metoda nie uwzględnia pola niejawnej długości dla klasy tablicy. Kod użytkownika powinien używać metod klasy Array do manipulowania tablicami.
public Field[] getDeclaredFields() throws SecurityException
Zwraca tablicę obiektów Field odzwierciedlających wszystkie pola zadeklarowane przez klasę lub interfejs reprezentowany przez ten obiekt Class. Obejmuje to pola publiczne, chronione, domyślne (pakietowe) i prywatne , ale wyklucza pola dziedziczone . Zwracane elementy tablicy nie są sortowane i nie mają określonej kolejności. Ta metoda zwraca tablicę o długości 0, jeśli klasa lub interfejs nie deklaruje żadnych pól lub jeśli ten obiekt klasy reprezentuje typ pierwotny, klasę tablic lub void.
A jeśli potrzebuję wszystkich pól ze wszystkich klas nadrzędnych? Potrzebny jest pewien kod, np. Z https://stackoverflow.com/a/35103361/755804 :
źródło
Z samouczków Java Reflection :
źródło