Feldklasse
Die Feldklasse definiert einige Methoden, mit denen die Art eines Feldes abfragt und den Wert eines Feldes festgelegt oder gelesen werden kann. Durch die Kombination dieser Methoden mit der ererbten Mitgliedsmethode können wir alle Informationen zur Felddeklaration herausfinden und Felder eines bestimmten Objekts oder einer bestimmten Klasse manipulieren.
Die GetGenericype -Methode gibt eine Typinstanz zurück, die den Deklarationstyp des Feldes darstellt. Für triviale Typen wie String oder Int gibt die Methode Klassenobjekte zurück, die ihm zugeordnet sind, wie z. B. String.Class und int.ClASSO für parametrisierte Typen wie List <Stri ng>, die Methode gibt eine Instanz der parametrisierten Frist zurück. Zum Beispiel gibt die Methode für Typen wie t eine typariable Instanz zurück.
Die Legacy GetType -Methode gibt ein Klassenobjekt vom Feld des Feldes zurück. Bei trivialen Typen verhält sich die Methode genauso wie die GetGenericype -Methode. Wenn der deklarierte Typ des Feldes ein parametrisierter Typ ist, gibt die GetType -Methode das entsprechende Klassenobjekt für die Löschen des parametrisierten Typs zurück, dh das Klassenobjekt des ursprünglichen Typs. Zum Beispiel wird Gettype für ein als Liste der als Liste deklarierter Gettype die Klasse zurückgeben. Wenn der deklarierte Typ eines Feldes eine Typvariable ist, gibt die GetType -Methode das entsprechende Klassenobjekt zum Löschen der Typvariablen zurück. Angenommen, es gibt eine Klasse foo <ding>, und für Felder, die als T -Typ deklariert sind, gibt Getding YPE das Objekt zurück.
Klassenobjekt. Wenn Foo als Foo <erweitert nummer> deklariert wird, wird ype unter GET -Rückgabenummer.Class.
Wir können die IsenumConstant -Methode verwenden, um abzufragen, ob ein Feld eine Konstante ist, oder wir können die GET -und -festen Methoden verwenden, um den Wert des Feldes zu erhalten und festzulegen. Diese Methoden, die Objektzitate akzeptieren und den Objekt -ECT -Wert zurückgeben, haben eine gemeinsame Form sowie einige speziellere Formen, die direkt mit Grundtypen umgehen können. Alle diese Methoden akzeptieren ein Zitat, um das zu bedienende Objekt anzugeben. Für statische Felder wird dieses Objektzitat ignoriert, sodass Sie es auch festlegen können
Auf null einstellen. Die folgende Methode druckt den Wert des kurzen Feldes eines Objekts:
public static void printshortfield (Objekt O, String Name) löst NoSuchfieldException, illegalAccessexception {field field = o.getClass (). Getfield (Name); Short Value = (Short) Feld.get (o); System.out.println (Wert);Der Rückgabewert der GET -Methode kann jedes von diesem Feld verwiesene Objekt sein. Wenn das Feld ein primitiver Typ ist, gibt die Methode den entsprechenden Typ des Wrapper -Class -Objekts zurück. Für unser Feld vom Typ "Hort-Typ gibt die GET-Methode ein Objekt vom Typ Short, der den Wert des Feldes enthält, zurückgibt, und wenn er dem lokalen Variablenwert zugeordnet ist, wird der Objektwert automatisch nicht mehr enttäuscht.
Die Verwendung der Satzmethode ist ähnlich. Die Methode zum Einstellen des kurzen Feldes auf den bereitgestellten Wert kann so aussehen:
public static voi setshortfield (Objekt O, String -Name, Short NV) löst NoSuchfieldException, IllegalAccessException Field = 0.GetClass (). Getfield (Name) aus. Field .Set (o .nv);
Obwohl die SET Parameter des Objekttyps akzeptiert, können wir einen kurzen Wert direkt übergeben und ihn bei der Umstellung von Wickeln in ein kurzes Objekt einwickeln.
Wenn in der obigen Methode die Domäne des angegebenen Objekts unzugänglich ist und diese Zugriffskontrolle durchgesetzt wird, wird eine illegale Ausnahme von Accessexception ausgelöst. Wenn sich das übergebene Objekt von der Art der Domäne unterscheidet, wird eine illegalArgumentException -Ausnahme ausgeworfen. Wenn die Domäne nicht statisch ist und die Übergabe der Objektreferenz null ist, wird eine NullPointerexception-Ausnahme ausgelöst. Durch den Zugriff auf eine statische Domäne kann die Klasse initialisiert werden, sodass die Methode auch eine Ausnahme von AUCECTIninInitializerError ausführt.
Die Feldklasse verfügt auch über spezifische Methoden zum Erhalten und Festlegen von Grundtypen. Zum Beispiel können wir GetPrimitive7TyTe -Typen aufrufen und primitive 7TyP auf dem Feldobjekt festlegen, wobei Primitive7ype der (kapitalisierte) Grundtypname ist. Die GET -Methode kann in der folgenden Anweisung verwendet werden:
Short Value = field.getShhort (o);
Die SET -Methode kann in der folgenden Anweisung verwendet werden:
Field.SetShort (O, NV);
Die Verwendung von Wrapper-Objekten kann in den oben genannten Aussagen vermieden werden.
Die Feldklasse implementiert die kommentierte Schnittstelle, sodass wir auch nach Abschnitt 16.2 abfragen und auf die Domäne anwenden können.
Notizen zu.
Mit der oben beschriebenen Methode können wir das Feldobjekt verwenden, um jeden Wert zu manipulieren, aber wir sollten versuchen, es zu vermeiden. Da die Java -Sprache während der Kompilierungsperiode eines Programms so viele Programmierfehler auffängt, werden die weniger indirekten Methoden wie "IELD -Objekte" verwendet, wenn wir Code schreiben, desto mehr Fehler können vor dem Kompilieren in Code verhindert werden. Darüber hinaus können wir sehen, dass wir im vorherigen Code, um zu wissen, was genau passieren wird, offensichtlich viel mehr Energie für das Lesen von Code verbracht haben als bei direkter Verwendung von Domain -Namen direkt in gewöhnlicher Syntax.
Endfelder
Normalerweise wird ein Feld festgelegt
Ausnahme, das können wir erwarten, denn der Wert des endgültigen Feldes wird sich nie ändern. Es gibt jedoch einige besondere Fälle - beispielsweise in der benutzerdefinierten Deserialisierung (siehe Abschnitt 20.8.4) ist es sinnvoll, den Wert des endgültigen Feldes zu ändern, das wir nur durch Reflexion auf dem Instanzfeld erreichen können, und nur, wenn SetAccessible (True) auf das Feldobjekt aufgerufen wurde. Beachten Sie, dass es nicht ausreicht, SetAccessible (wahr) erfolgreich aufzurufen, und es muss in der Tat genannt werden.
Diese Fähigkeit wird für hochspezialisierte Kontexte bereitgestellt und ist nicht allgemeiner Zweck. Wir stellen sie vor, um die Integrität des Inhalts nur aufrechtzuerhalten. Wenn Sie in einem bestimmten Kontext herauskommen, z. B. eine angepasste Deserialisierung, kann die Änderung des Werts des endgültigen Feldes zu unerwarteten oder sogar katastrophalen Konsequenzen führen. Außerhalb dieser Kontexte gibt es keine Garantie dafür, dass Änderungen am endgültigen Feld sichtbar sind. Selbst in solchen Kontexten muss sichergestellt werden, dass der Sicherheitsmechanismus die Ausführung des Codes bei der Codierung dieser Technologie nicht behindert. Durch das Ändern des endgültigen Feldes mit einem Wert der konstanten Variablen (siehe Abschnitt 2.2.3) wird diese Änderung unsichtbar, es sei denn, eine solche Änderung wird unter Verwendung der Reflexion erreicht.
Methodenklasse
Die Methodenklasse und ihre erblichen Methoden aus der Mitgliedsklasse ermöglichen es uns, die vollständigen Informationen über die Methodenerklärung zu erhalten:
"Public Type GetgenericReturnTypeo: Diese Methode gibt ein Typobjekt des Rückgabetyps der Zielmethode zurück. Wenn die Zielmethode für die Rückgabe von Void deklariert wird, gibt die Methode void zurück.classo
"Public Type [] getGenericParameterTypes (): Diese Methode gibt ein Array von Typobjekten aller Parametertypen der Zielmethode zurück, die in der Reihenfolge der Deklaration der Parameter im Array gespeichert werden. Wenn die Zielmethode keine Parameter enthält, gibt die Methode ein leeres Array zurück.
.
Wenn die Zielmethode keine Ausnahmen deklariert, gibt die Methode ein leeres Array zurück.
Java bietet auch GetReturnType-, GetParameterTypes- und GetExceptionTypes -Methoden zur Rückgabe von CL als "Objekt anstelle von Typ -Objekten. Genau wie bei der Verwendung von Feldtypen, parametrisierte Typ- und Typvariablen werden durch das Klassenobjekt dargestellt, das ihrer Erase entspricht.
Die Methodenklasse implementiert Annotierelement, und wir können die in Abschnitt 16.2 erörterten Anmerkungen an die Methode abfragen. Darüber hinaus bietet die Methodenklasse GetParameterAnnotations, um Zugriff auf Anmerkungen zu gewährleisten, die auf Methodenparameter angewendet werden. Die GetParameterAnnotations -Methode kann ein Annotationsarray zurückgeben, wobei jedes Element des äußersten Arrays den Parametern der Methode entspricht. Wenn ein Parameter keine Anmerkungen hat, gibt die Methode ein Annotationsarray mit Länge 0 für diesen Parameter zurück. Wenn die vom Methodenobjekt dargestellte Methode selbst ein Annotationselement ist, gibt die Methode getDefaultValue ein Objekt zurück, das den Standardwert des Elements darstellt. Wenn das Methodenobjekt selbst kein Annotationselement ist oder kein Standardwert hat, gibt die Methode die NULL.Method -Klasse zurück. Die Methode der Methode implementiert auch genericDeclaration, sodass die Methode von GettTypeParametern definiert ist, wodurch ein Array von typariablen Objekten zurückgegeben wird. Wenn das angegebene Methodenobjekt keine generische Methode darstellt, gibt die Methode ein leeres Array zurück.
Wir können die Isvarargs -Methode verwenden, um zu überprüfen
Die interessanteste Möglichkeit, ein Methodenobjekt zu verwenden, besteht darin, sich reflektierend zu bezeichnen:
.Public Object Incoke (Objekt in diesem Objekt… args) löst illegalacessException, illegalArgumentException, ArgetException unter nvocation aus: Diese Methode ruft die durch das Methodenobjekt auf diesem Objekt definierte Methode auf und verwendet den Wert von Args, um die Parameter der aufgerufenen Methode festzulegen. Bei nicht-statischen Methoden bestimmt die tatsächliche Art von Onthis, welche Implementierung der Methode aufgerufen werden soll, während für statische Methoden auf diese Weise ignoriert und normalerweise auf Null eingestellt wird. Die Anzahl der Werte von Args muss mit der tatsächlichen Anzahl der Parameter der aufgerufenen Methode übereinstimmen, und die Typen dieser Werte müssen alle den Parametern der aufgerufenen Methode zugeordnet sein. Andernfalls erhalten wir die Ausnahme von LlegalargumentException. Beachten Sie, dass der letzte Parameter der Variablenzitiermethode ein Array ist. Daher müssen wir das Array mit den "veränderlichen" Zitaten füllen, an denen wir tatsächlich passieren möchten. Wenn wir eine Methode aufrufen möchten, die wir keinen Zugriff haben, wird die Methode eine illegale Accessexception -Ausnahme ausgelegt. Wenn die aufgerufene Methode nicht die Methode des On -Objekts ist, werfen die Methode eine legalargumentExcepti auf die Ausnahme. Wenn es null ist und nicht statisch ist, wirft die Methode eine Nr. 1Pointerexception-Ausnahme aus. Wenn dieses Methodenobjekt eine statische Methode darstellt und die Klasse, die deklariert, dass die statische Methode noch im Status initialisiert wird, wird die Methode eine Ausnahme von ExecesIn Worker NitializerError ausgelegt. Wenn die aufgerufene Methode eine außerirdische Macht hat, wird die Ausnahme von InvocationTargetException ausgelöst.
Wenn wir die Invoke -Methode verwenden, können wir den Grundtyp direkt übergeben oder eine geeignete Wrapper -Klasse verwenden. Der von der Wrapper -Klasse dargestellte Typ muss dem von der Methode deklarierten Parametertyp zugeordnet werden. Wir können Long-, Float oder Double-Doppeltyp-Zitate verwenden, aber wir können doppelte Zitate mit langen oder float-Typen nicht verwenden, da doppelt nicht lang oder Hafer zugeordnet werden kann. Die von der Invoke -Methode zurückgegebene Verarbeitungsmethode des Objekts entspricht dem Feld.get, der den Grundtyp der ihnen entsprechenden Wrapper -Klasse zurückgibt. Wenn die Methode für void deklariert ist, gibt die Invoke -Methode NULL zurück,
Einfach ausgedrückt, wenn wir Invoke verwenden, um Methoden anzurufen, können wir nur rechtliche Parameter in der Java -Sprache verwenden.
Priorität mit dem gleichen Typ und Wert. Zum Beispiel den folgenden Anruf
return Str.Indexof (".", 8);Es kann in der folgenden Form unter Verwendung von Reflexion geschrieben werden:
Throwable Fas; Versuchen Sie {Method indexm = string.class. getMethod ("index0f", string.class, int.class); return (Integer) Indexm.invoke (str, ",", 8); } catch (NoSuchMethodException e) {fehler = e; } catch (invocationTargetException e) {fas = e .getCause (); } catch (illegalAccessException e) {fehler = e; } werfen fas;Obwohl die Sicherheitsprüfungen des Compiler für direkte Anrufe nur bei der Verwendung von Invoke zur Laufzeit bei der Verwendung von Reflexionen durchgeführt werden können, verfügt der Reflexions-basierte Code über semantisch äquivalente Sicherheitsprüfungen für den direkten Code. Zugriffsüberprüfungen können auf etwas andere Weise durchgeführt werden. Der Sicherheitsmanager kann den Zugriff auf eine Methode in unserem Paket verweigern, auch wenn wir ihn direkt anrufen können.
Wenn wir diese Anlaufform verwenden können, haben wir guten Grund, sie zu vermeiden. Es wäre jedoch sinnvoll, wenn wir die Methode für Invoke oder GET/SET verwenden, wenn wir einen Debugger oder eine andere generische Anwendung schreiben, die die Benutzereingabe als Operation für Objekte interpretieren muss. Das Methodenobjekt kann in gewissem Maße als Methodenzeiger verwendet werden, ähnlich wie in anderen Sprachen, aber wir haben bessere Werkzeuge, insbesondere Schnittstellen, abstrakte Klassen und verschachtelte Klassen, die verwendet werden können, um mit Problemen umzugehen, die normalerweise mit Methodenzeiger in anderen Sprachen gelöst werden.