Java Transiente Schlüsselwörter
1. Die Funktions- und Verwendungsmethode des Transientes
Wir alle wissen, dass das Objekt serialisiert werden kann, solange ein Objekt die serilisierbare Schnittstelle implementiert. Dieses Serialisierungsmodell von Java bietet Entwicklern eine große Bequemlichkeit. Wir müssen uns nicht auf den spezifischen Serialisierungsprozess beziehen. Solange diese Klasse die serilisierbare Schnittstelle implementiert, werden alle Eigenschaften und Methoden dieser Klasse automatisch serialisiert.
Im tatsächlichen Entwicklungsprozess stoßen wir jedoch häufig auf solche Probleme. Einige Eigenschaften dieser Klasse müssen serialisiert werden, während andere Eigenschaften nicht serialisiert werden müssen. Wenn ein Benutzer beispielsweise einige sensible Informationen (z. B. Passwörter, Bankkartennummern usw.) hat, möchte er aus Sicherheitsgründen nicht in Netzwerkoperationen übertragen werden (hauptsächlich mit Serialisierungsvorgängen ist ein lokaler Serialisierungs -Cache anwendbar) und die Variablen, die diesen Informationen entsprechen, können mit dem transienten Schlüsselwort hinzugefügt werden. Mit anderen Worten, der Lebenszyklus dieses Feldes liegt nur im Gedächtnis des Anrufers und wird nicht zur Persistenz auf die Festplatte geschrieben.
Kurz gesagt, Javas transientes Keyword bietet uns Komfort. Sie müssen nur die Serilisable -Schnittstelle implementieren und das Schlüsselwort -Transienten vor den Attributen hinzufügen, die nicht serialisiert werden müssen. Bei der Serialisierung des Objekts wird dieses Attribut nicht mit dem angegebenen Ziel serialisiert.
Der Beispielcode lautet wie folgt:
importieren java.io.fileinputstream; import Java.io.filenotFoundException; import Java.io.FileOutputStream; Import Java.io.ioException; Java.io.objectinputStream importieren Java.io. Variable * Beachten Sie, dass beim Lesen der Reihenfolge des Lesens von Daten mit der Reihenfolge der Speicherung von Daten übereinstimmt. user.SetUnername ("Alexia"); user.setPasswd ("123456"); System.out.println ("vor serialisierbar lesen:"); System.out.println ("Benutzername:" + user.getUnername ()); System.err.println ("Passwort:" + user.getPasswd ()); try {ObjectOutputStream os = new ObjectOutputStream (new FileOutputStream ("c: /User.txt")); os.writeObject (Benutzer); // Schreiben Sie das Benutzerobjekt in die Datei os.flush (); os.close (); } catch (FilenotFoundException e) {e.printstacktrace (); } catch (ioException e) {e.printstacktrace (); } try {ObjectInputStream ist = new ObjectInputStream (neuer FileInputStream ("c: /user.txt"); user = (user) is.ReadObject (); // Die Daten des Benutzers aus dem Stream lesen.CLOSE (); System.out.println ("/nread nach serialisierbar:"); System.out.println ("Benutzername:" + user.getUnername ()); System.err.println ("Passwort:" + user.getPasswd ()); } catch (FilenotFoundException e) {e.printstacktrace (); } catch (ioException e) {e.printstacktrace (); } catch (classNotFoundException e) {e.printstacktrace (); }}} Klasse Benutzer implementiert serialisierbar {private statische endgültige lange Serialversionuid = 8294180014912103005L; privater String -Benutzername; private transiente String Passwd; public String getUnername () {return userername; } public void setUnername (String -Benutzername) {this.username = userername; } public String getPasswd () {return passwd; } public void setpasswd (String passwd) {this.passwd = passwd; }}Die Ausgabe ist:
Lesen Sie vor serialisierbar: Benutzername: AlexiaPassword: 123456Rea nach Serialisierbar: Benutzername: AlexiaPassword: NULL
Das Feld Passwort ist null, was bedeutet, dass während der Deserialisierung keine Informationen aus der Datei erhalten wurden.
2. Zusammenfassung der vorübergehenden Nutzung
1) Sobald die Variable durch transient modifiziert ist, ist die Variable nicht mehr Teil der Persistenz des Objekts, und auf den Inhalt der Variablen kann nach der Serialisierung nicht zugegriffen werden.
2) Das transiente Schlüsselwort kann nur Variablen ändern, jedoch nicht Methoden und Klassen. Beachten Sie, dass lokale Variablen nicht durch transiente Schlüsselwörter geändert werden können. Wenn eine Variable eine benutzerdefinierte Klassenvariable ist, muss die Klasse die serialisierbare Schnittstelle implementieren.
3) Variablen, die durch das transiente Schlüsselwort modifiziert wurden, können nicht mehr serialisiert werden. Eine statische Variable kann nicht serialisiert werden, unabhängig davon, ob sie durch transient geändert wird.
Der dritte Punkt kann verwirrend sein, da ich feststellte, dass das Programmlaufergebnis nach dem Hinzufügen des statischen Schlüsselworts in das Feld Benutzername in der Benutzerklasse bleibt unverändert, dh der Benutzername des statischen Typs wird ebenfalls als "Alexia" gelesen. Ist das nicht dem dritten Punkt widersprüchlich? Tatsächlich ist es so: Der dritte Punkt ist in der Tat richtig (eine statische Variable kann nicht serialisiert werden, unabhängig davon, ob er durch transient modifiziert ist). Nach der Deserialisierung ist der Benutzername der statischen Variablen in der Klasse der Wert der entsprechenden statischen Variablen im aktuellen JVM. Dieser Wert wird nicht aus der Deserialisierung im JVM abgeleitet. Glauben Sie es nicht? OK, lassen Sie es mich unten beweisen:
importieren java.io.fileinputstream; import Java.io.filenotFoundException; import Java.io.FileOutputStream; Import Java.io.ioException; Java.io.objectinputStream importieren Java.io. Variable * Beachten Sie, dass beim Lesen der Reihenfolge des Lesens von Daten mit der Reihenfolge der Speicherung von Daten übereinstimmen muss user.SetUnername ("Alexia"); user.setPasswd ("123456"); System.out.println ("vor serialisierbar lesen:"); System.out.println ("Benutzername:" + user.getUnername ()); System.err.println ("Passwort:" + user.getPasswd ()); try {ObjectOutputStream os = new ObjectOutputStream (new FileOutputStream ("c: /User.txt")); os.writeObject (Benutzer); // Schreiben Sie das Benutzerobjekt in die Datei os.flush (); os.close (); } catch (FilenotFoundException e) {e.printstacktrace (); } catch (ioException e) {e.printstacktrace (); } try {// Ändern Sie den Benutzernamenwert vor der Deserialisierung user.username = "jmwang"; ObjectInputStream ist = new ObjectInputStream (neuer FileInputStream ("c: /User.txt"); user = (user) is.ReadObject (); // Die Daten des Benutzers aus dem Stream lesen.CLOSE (); System.out.println ("/nread nach serialisierbar:"); System.out.println ("Benutzername:" + user.getUnername ()); System.err.println ("Passwort:" + user.getPasswd ()); } catch (FilenotFoundException e) {e.printstacktrace (); } catch (ioException e) {e.printstacktrace (); } catch (classNotFoundException e) {e.printstacktrace (); }}} Klasse Benutzer implementiert serialisierbar {private statische endgültige lange Serialversionuid = 8294180014912103005L; öffentlicher statischer String -Benutzername; private transiente String Passwd; public String getUnername () {return userername; } public void setUnername (String -Benutzername) {this.username = userername; } public String getPasswd () {return passwd; } public void setpasswd (String passwd) {this.passwd = passwd; }}Das Betriebsergebnis ist:
Lesen Sie vor serialisierbar: Benutzername: AlexiaPassword: 123456Rea nach Serialisierbar: Benutzername: JMWangPassword: NULL
Dies bedeutet, dass der Wert des Benutzernamens der statischen Variablen in der Deserialized -Klasse der Wert der entsprechenden statischen Variablen in der aktuellen JVM, der modifizierten JMWang, nicht der Wert Alexia während der Serialisierung ist.
3.. Transiente Verwendungsdetails - Können Variablen, die durch das transiente Schlüsselwort modifiziert wurden, wirklich serialisiert werden?
Denken Sie an die folgenden Beispiele:
importieren java.io.externalizable; import java.io.file; import java.io.fileinputstream; import Java.io.FileOutputStream; Import Java.io.ioxception; import Java.io.objectinputstream; Import Java.io. @date 2013-10-15 * */public class externalizabletest implementiert externalisierbar {private transiente String content = "Ja, ich werde serialisiert, unabhängig davon, ob ich durch das transiente Schlüsselwort modifiziert bin oder nicht"; @Override public void writeExternal (ObjectOutput Out) löst ioException {out.writeObject (Inhalt) aus; } @Override public void ReadExternal (ObjectInput in) löst IOException, classNotFoundException {content = (string) in.readObject () aus; } public static void main (String [] args) löst eine Ausnahme aus {externalizabletest et = new externalizablEldest (); ObjectOutput out = new ObjectOutputStream (neuer FileOutputStream (neue Datei ("Test")); out.writeObject (et); ObjectInput in = new ObjectInputStream (neuer FileInputStream (neue Datei ("Test")); et = (externalizablEtest) in.readObject (); System.out.println (etcontent); out.close (); in.close (); }}Wird die Inhaltsvariable serialisiert? OK, ich habe alle Antworten ausgegeben, ja, das Ergebnis ist:
Ja, ich werde serialisiert, unabhängig davon, ob ich durch das transiente Schlüsselwort geändert werde oder nicht
Warum ist das? Ist es nicht gesagt, dass die Variablen der Klasse nach dem vorübergehenden Schlüsselwort nicht serialisiert werden?
Wir wissen, dass in Java die Objekt -Serialisierung durch Implementierung von zwei Schnittstellen implementiert werden kann. Wenn die serialisierbare Schnittstelle implementiert ist, wird die gesamte Serialisierung automatisch durchgeführt. Wenn die externalisierbare Schnittstelle implementiert ist, kann automatisch nichts serialisiert werden. Sie müssen die Variable manuell angeben, die in der WriteExternal -Methode serialisiert werden soll, was nichts damit zu tun hat, ob sie durch transient geändert wird. Daher gibt das zweite Beispiel den durch den variablen Inhalt initialisierten Inhalt aus, nicht durch NULL.
Danke fürs Lesen, ich hoffe, es kann Ihnen helfen. Vielen Dank für Ihre Unterstützung für diese Seite!