Ich bin etwas verwirrt über den Unterschied zwischen der getFields
Methode und der getDeclaredFields
Methode bei der Verwendung von Java Reflection.
Ich habe gelesen, dass getDeclaredFields
Sie Zugriff auf alle Felder der Klasse haben und getFields
nur öffentliche Felder zurückgeben. Wenn dies der Fall ist, warum würden Sie es nicht immer verwenden getDeclaredFields
?
Kann jemand bitte näher darauf eingehen und den Unterschied zwischen den beiden Methoden erklären und wann / warum Sie eine über die andere verwenden möchten?
java
reflection
BlackHatSamurai
quelle
quelle
getField
kann ein Feld von einer Oberklasse erben,getDeclaredField
kann es aber nicht.getDeclaredField
Beschränken Sie sich auf die Klasse, für die Sie die Funktion aufrufen.getField
kann aber nicht auf private Mitglieder zugreifenAntworten:
getFields ()
Alle
public
Felder bilden die gesamte Klassenhierarchie.getDeclaredFields ()
Alle Felder, unabhängig von ihrer Zugänglichkeit, jedoch nur für die aktuelle Klasse, keine Basisklassen, von denen die aktuelle Klasse möglicherweise erbt.
Um alle Felder in der Hierarchie nach oben zu bringen, habe ich die folgende Funktion geschrieben:
Die
exclusiveParent
Klasse wird bereitgestellt, um das Abrufen von Feldern aus zu verhindernObject
. Es kann sein,null
wenn Sie dieObject
Felder wollen .Zur Verdeutlichung
Lists.newArrayList
kommt aus Guave.Aktualisieren
Zu Ihrer Information , der obige Code wird auf GitHub in meinem LibEx- Projekt in ReflectionUtils veröffentlicht .
quelle
Field#get
und ähnliche Methoden verwendet werden können. Mit anderen Worten, dieser Ansatz ermöglicht der aktuellen Klasse keinen Zugriff auf die private Schnittstelle ihrer Oberklasse, wie dies bei der typischen Kompilierung nicht der Fall ist.setAccessible
und es ist kein Sicherheitsmanager vorhandenprivate
Felder nur zugegriffen werden kanngetDeclaredFields
, ist dies klassenspezifisch. Jedes Feld (auch mit demselben Typ und Namen) wäre eine unterschiedlicheField
Instanz.Wie bereits erwähnt, werden
Class.getDeclaredField(String)
nur die Felder angezeigt,Class
in denen Sie sie aufrufen.Wenn Sie
Field
in derClass
Hierarchie nach suchen möchten , können Sie diese einfache Funktion verwenden:Dies ist beispielsweise nützlich, um ein
private
Feld aus einer Oberklasse zu finden . Wenn Sie den Wert ändern möchten, können Sie ihn auch folgendermaßen verwenden:quelle
try try { field = clazz.getDeclaredField(name); } catch (NoSuchFieldException e) { clazz = clazz.getSuperclass(); if(clazz==null){ throw e; } }
public Field[] getFields() throws SecurityException
Gibt ein Array zurück, das Feldobjekte enthält, die alle zugänglichen öffentlichen Felder der Klasse oder Schnittstelle widerspiegeln, die von diesem Klassenobjekt dargestellt werden. Die zurückgegebenen Elemente im Array sind nicht sortiert und befinden sich nicht in einer bestimmten Reihenfolge. Diese Methode gibt ein Array der Länge 0 zurück, wenn die Klasse oder Schnittstelle keine zugänglichen öffentlichen Felder hat oder wenn es eine Array-Klasse, einen primitiven Typ oder eine Leere darstellt.
Wenn dieses Class-Objekt eine Klasse darstellt, gibt diese Methode die öffentlichen Felder dieser Klasse und aller ihrer Oberklassen zurück. Wenn dieses Class-Objekt eine Schnittstelle darstellt, gibt diese Methode die Felder dieser Schnittstelle und aller ihrer Superschnittstellen zurück.
Das implizite Längenfeld für die Array-Klasse wird von dieser Methode nicht berücksichtigt. Benutzercode sollte die Methoden der Klasse Array verwenden, um Arrays zu bearbeiten.
public Field[] getDeclaredFields() throws SecurityException
Gibt ein Array von Feldobjekten zurück, die alle Felder widerspiegeln, die von der Klasse oder Schnittstelle deklariert wurden, die von diesem Klassenobjekt dargestellt wird. Dies umfasst öffentliche, geschützte, Standardzugriffe (Paketzugriffe) und private Felder, schließt jedoch geerbte Felder aus. Die zurückgegebenen Elemente im Array sind nicht sortiert und befinden sich nicht in einer bestimmten Reihenfolge. Diese Methode gibt ein Array der Länge 0 zurück, wenn die Klasse oder Schnittstelle keine Felder deklariert oder wenn dieses Class-Objekt einen primitiven Typ, eine Array-Klasse oder void darstellt.
Und was ist, wenn ich alle Felder aus allen übergeordneten Klassen benötige? Es wird Code benötigt, z. B. von https://stackoverflow.com/a/35103361/755804 :
quelle
Aus Java Reflection-Tutorials :
quelle