Java - Serialisierung

Java bietet einen Mechanismus namens Objektserialisierung, bei dem ein Objekt als eine Folge von Bytes dargestellt werden kann, die die Daten des Objekts sowie Informationen über den Objekttyp und die im Objekt gespeicherten Datentypen enthält.

Nachdem ein serialisiertes Objekt in eine Datei geschrieben wurde, kann es aus der Datei gelesen und deserialisiert werden, dh die Typinformationen und Bytes, die das Objekt und seine Daten darstellen, können verwendet werden, um das Objekt im Speicher neu zu erstellen.

Am beeindruckendsten ist, dass der gesamte Prozess JVM-unabhängig ist, was bedeutet, dass ein Objekt auf einer Plattform serialisiert und auf einer völlig anderen Plattform deserialisiert werden kann.

Klassen ObjectInputStream und ObjectOutputStream sind Streams auf hoher Ebene, die die Methoden zum Serialisieren und Deserialisieren eines Objekts enthalten.

Die ObjectOutputStream-Klasse enthält viele Schreibmethoden zum Schreiben verschiedener Datentypen, wobei jedoch eine Methode besonders hervorzuheben ist:

public final void writeObject(Object x) throws IOException

Die obige Methode serialisiert ein Objekt und sendet es an den Ausgabestream. In ähnlicher Weise enthält die ObjectInputStream-Klasse die folgende Methode zum Deserialisieren eines Objekts:

public final Object readObject() throws IOException, ClassNotFoundException

Diese Methode ruft das nächste Objekt aus dem Stream ab und deserialisiert es. Der Rückgabewert ist Object, daher müssen Sie ihn in den entsprechenden Datentyp umwandeln.

Um zu demonstrieren, wie die Serialisierung in Java funktioniert, werde ich die Employee-Klasse verwenden, die wir zu Beginn des Buches besprochen haben. Angenommen, wir haben die folgende Employee-Klasse, die die serialisierbare Schnittstelle implementiert:

Beispiel

public class Employee implements java.io.Serializable {
   public String name;
   public String address;
   public transient int SSN;
   public int number;
   
   public void mailCheck() {
      System.out.println("Mailing a check to " + name + " " + address);
   }
}

Beachten Sie, dass zwei Bedingungen erfüllt sein müssen, damit eine Klasse erfolgreich serialisiert werden kann:

  • Die Klasse muss die Schnittstelle java.io.Serializable implementieren.

  • Alle Felder in der Klasse müssen serialisierbar sein. Wenn ein Feld nicht serialisierbar ist, muss es markiert werdentransient.

Wenn Sie neugierig sind, ob eine Java-Standardklasse serialisierbar ist oder nicht, lesen Sie die Dokumentation für die Klasse. Der Test ist einfach: Wenn die Klasse java.io.Serializable implementiert, ist sie serialisierbar. sonst ist es nicht.

Ein Objekt serialisieren

Die ObjectOutputStream-Klasse wird zum Serialisieren eines Objekts verwendet. Das folgende SerializeDemo-Programm instanziiert ein Employee-Objekt und serialisiert es in eine Datei.

Nach Abschluss der Programmausführung wird eine Datei mit dem Namen employee.ser erstellt. Das Programm generiert keine Ausgabe, studiert jedoch den Code und versucht festzustellen, was das Programm tut.

Note - Wenn Sie ein Objekt in eine Datei serialisieren, besteht die Standardkonvention in Java darin, der Datei eine zu geben .ser Erweiterung.

Beispiel

import java.io.*;
public class SerializeDemo {

   public static void main(String [] args) {
      Employee e = new Employee();
      e.name = "Reyan Ali";
      e.address = "Phokka Kuan, Ambehta Peer";
      e.SSN = 11122333;
      e.number = 101;
      
      try {
         FileOutputStream fileOut =
         new FileOutputStream("/tmp/employee.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
         out.writeObject(e);
         out.close();
         fileOut.close();
         System.out.printf("Serialized data is saved in /tmp/employee.ser");
      } catch (IOException i) {
         i.printStackTrace();
      }
   }
}

Deserialisieren eines Objekts

Das folgende DeserializeDemo-Programm deserialisiert das im SerializeDemo-Programm erstellte Employee-Objekt. Studieren Sie das Programm und versuchen Sie, seine Ausgabe zu bestimmen -

Beispiel

import java.io.*;
public class DeserializeDemo {

   public static void main(String [] args) {
      Employee e = null;
      try {
         FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         e = (Employee) in.readObject();
         in.close();
         fileIn.close();
      } catch (IOException i) {
         i.printStackTrace();
         return;
      } catch (ClassNotFoundException c) {
         System.out.println("Employee class not found");
         c.printStackTrace();
         return;
      }
      
      System.out.println("Deserialized Employee...");
      System.out.println("Name: " + e.name);
      System.out.println("Address: " + e.address);
      System.out.println("SSN: " + e.SSN);
      System.out.println("Number: " + e.number);
   }
}

Dies führt zu folgendem Ergebnis:

Ausgabe

Deserialized Employee...
Name: Reyan Ali
Address:Phokka Kuan, Ambehta Peer
SSN: 0
Number:101

Hier sind folgende wichtige Punkte zu beachten:

  • Der try / catch-Block versucht, eine ClassNotFoundException abzufangen, die von der readObject () -Methode deklariert wird. Damit eine JVM ein Objekt deserialisieren kann, muss sie den Bytecode für die Klasse finden können. Wenn die JVM während der Deserialisierung eines Objekts keine Klasse finden kann, löst sie eine ClassNotFoundException aus.

  • Beachten Sie, dass der Rückgabewert von readObject () in eine Mitarbeiterreferenz umgewandelt wird.

  • Der Wert des SSN-Felds war 11122333, als das Objekt serialisiert wurde. Da das Feld jedoch vorübergehend ist, wurde dieser Wert nicht an den Ausgabestream gesendet. Das SSN-Feld des deserialisierten Employee-Objekts ist 0.