Serializarea obiectelor

Serializarea este macanismul prin care starea obiectelor poate fi citită din memorie şi trimisă printr-un flux către o destinaţie (o altă aplicaţie, fişier, reţea, etc.). Procesul invers prin care un obiect este reîncărcat în memorie prin citirea acestuia dintr-un flux se numeşte deserializare. Pentru serilaizarea şi deserializarea obiectelor limbajul java pune la dispoziţie fluxurile ObjectInputStream şi ObjectOutputStream.

import java.util.*;
import java.io.*;
 
public class SerializareExemplu {
      public static void main(String[] args) throws Exception{
            AlienFactory f = new AlienFactory();
 
            Alien a = f.createAlien("axx");
            Alien b = f.createAlien("abb");
 
            f.freezAlien(a,"aliena.dat");
            f.freezAlien(b,"alienb.dat");
 
            Alien x = f.unfreezAlien("alienb.dat");
            Alien y = f.unfreezAlien("aliena.dat");
 
            System.out.println(x);
            System.out.println(y);
      }
}//.class
 
class AlienFactory{
      Alien createAlien(String name){
            Alien z = new Alien(name);
            System.out.println(z+" is alive.");
            return z;
      }
 
      void freezAlien(Alien a, String storeRecipientName) throws IOException{
            ObjectOutputStream o =
              new ObjectOutputStream(
                new FileOutputStream(storeRecipientName));
 
            o.writeObject(a);
            System.out.println(a+":I'll be back.");
      }
 
      Alien unfreezAlien(String storeRecipientName) throws IOException, ClassNotFoundException{
             ObjectInputStream in =
                    new ObjectInputStream(
                      new FileInputStream(storeRecipientName));
             Alien x = (Alien)in.readObject();
             System.out.println(x+":I'm back.");
             return x;
      }
 
}//.class
 
 
class Alien implements Serializable{
      String name;
      transient int id;
 
      public Alien(String n) {
            this.name = n;
            id =  (int)(Math.random()*100);
      }
      public void move(){System.out.println("Alien is moving."+this);}
      public String toString(){return "[alien="+name+":id="+id+"]";}
}//.class

Pentru implementarea mecanismului de serializare / deserializare se poate folosi şi interfaţa Externalizable ce permite controlul mai fin al procesului de salvare şi încărcare a obiectelor. Această interfaţă extinde interfaţa Serializable şi defineşte metodele writeExternal() şi readExternal() în cadrul cărora trebui implementat codul pentru scrierea şi citire obiectelor. Clasa ce implementează această interfaţă trebuie obligatoriu să aibă definit constructorul implicit (având specificatorul de acces public).

Dacă se doreşte ca un anumit atribut al unui obiect serializat să nu fie salvat atunci se poate folosi cuvântul cheie transient în faţa declaraţiei atributului respecitv.

import java.util.*;
import java.io.*;
 
public class SerializareExemplu2 {
 
public static void main(String[] args) {
      Tren tr = new Tren();
      Locomotiva l = new Locomotiva("XYZ", new Engine("diesel"));
      Vagon v1 = new Vagon(1,20);
      Vagon v2 = new Vagon(2,89);
      Vagon v3 = new Vagon(3,53);
 
      tr.addVagon(v1);tr.addVagon(v2);tr.addVagon(v3);
      tr.addLocomotiva(l);
 
      System.out.println(tr);
 
      tr.save("trenX");
 
      try {
            Tren t2 = Tren.load("trenX");
            System.out.println(t2);
      } catch (IOException e) {
            e.printStackTrace();
      } catch (ClassNotFoundException e) {
            e.printStackTrace();
      }
 
}
 
}
 
class Tren implements Serializable{
      LinkedList t = new LinkedList();
      transient int id;
 
      Tren(){
            id = (int)(Math.random()*1000);
      }
 
      void addVagon(Vagon v){
            t.addLast(v);
      }
 
      void addLocomotiva(Locomotiva e){
            t.addFirst(e);
      }
 
      void save(String fileName) {
            try {
                  ObjectOutputStream o =
                    new ObjectOutputStream(
                      new FileOutputStream(fileName));
                  o.writeObject(this);   
                  System.out.println("Tren salvat in fisier");
            } catch (IOException e) {
                  System.err.println("Trenul nu poate fi scris in fisiser.");
                  e.printStackTrace();
            }
 
      }
 
      static Tren load(String fileName) throws IOException, ClassNotFoundException {     
                  ObjectInputStream in =
                    new ObjectInputStream(
                      new FileInputStream(fileName));
                  Tren t = (Tren)in.readObject();    
                  return t;  
      }
 
      public String toString(){
            String x="Tren ID="+id+" ";
            for (Iterator i = t.iterator(); i.hasNext();) {
                  Object element = (Object) i.next();
                  x+=element;
            }
            return x;
      }    
}
 
class Vagon implements Externalizable{
      int nr;
      int nrPasageri;
 
      public Vagon(){}
 
      public Vagon(int i,int p) {
            nr=i;
            nrPasageri = p;
      }
 
      @Override
      public String toString() {
            return "<"+nr+" pasageri="+nrPasageri+">";
      }
 
      public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            nr = in.readInt();
            nrPasageri=in.readInt();
      }
 
      public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(nr);
            out.writeInt(nrPasageri);
      }
}
 
class Locomotiva implements Serializable{
      String marca;
      Engine e;
 
      /**
       * @param marca
       * @param e
       */
      public Locomotiva(String marca, Engine e) {
            this.marca = marca;
            this.e = e;
      }
 
      @Override
      public String toString() {
            return "[Locomotiva"+marca+" "+e+"]";
      }
 
}
 
class Engine implements Serializable{
      String tip;
      public Engine(String t) {
            tip = t;
      }
      @Override
      public String toString() {
            return "-"+tip+"-";
      }
}