18.2. Serialisering af egne klasser

Det er ikke alle klasser, der må/kan serialiseres. For eksempel giver det ikke mening at serialisere en datastrøm til en forbindelse over netværket (eller bare til en fil). Hvordan skulle systemet genskabe en forbindelse, der har været gemt på harddisken i tre uger? Den anden ende af netværksforbindelsen vil formentlig være væk på det tidspunkt (og filen kan være flyttet eller slettet).

18.2.1. Interfacet Serializable

Serializable-interfacet, der ingen metoder har defineret, bruges til at markere, at objekter godt må serialiseres. Hvis en klasse implementerer Serializable, har man fortalt Java at objekter af denne type godt kan serialiseres.

Prøver man alligevel at serialisere et objekt der ikke er Serializable, opstår der en køretidsfejl. Derfor implementerer f.eks. FileWriter og Socket ikke Serializable.

18.2.2. Nøgleordet transient

Ud over, at der kan findes objekt-typer, som overhovedet ikke kan serialiseres, kan det også ske, at der er visse dele af et objekts data, man ikke ønsker serialiseret. Hvis et objekt indeholder midlertidige data (f.eks. fortrydelses-information i et tekstbehandlingsprogram), kan man markere de midlertidige datafelter i klassen med nøgleordet transient.

18.2.3. Eksempel

Eksemplet herunder viser en klasse, der kan serialiseres (implements Serializable), med en transient variabel (tmp). Hvis et Data-objekt serialiseres, vil a blive gemt i byte-sekvensen, men tmp vil ikke.

Af bekvemmelighedsgrunde er der også lavet en toString()-metode.

import java.io.*;
public class Data implements Serializable
{
  public int a;
  public transient int tmp;    // transiente data bliver ikke serialiseret

  public String toString()
  { 
    return "Data: a="+a+" tmp="+tmp;
  }
}

Her er et program, der læser en vektor af Data-objekter, tilføjer et og gemmer den igen.

import java.util.*;
public class HentOgGemData
{
  public static void main(String arg[]) throws Exception
  {
    Vector v;
    try {
      v = (Vector) Serialisering.hent("data.ser");
      System.out.println("Indlæst: "+v);
    } catch (Exception e) {
      v = new Vector();
      System.out.println("Oprettet: "+v);
    }

    Data d = new Data();
    d.a   = (int) (Math.random()*100);
    d.tmp = (int) (Math.random()*100);
    v.addElement(d);

    System.out.println("Gemt: "+v);
    Serialisering.gem(v,"data.ser");
  }
}

Resultatet bliver:

Oprettet: []
Gemt: [Data: a=88 tmp=2]

Køres programmet igen fås:

Læst: [Data: a=88 tmp=0]
Gemt: [Data: a=88 tmp=0, Data: a=10 tmp=10]

og

Læst: [Data: a=88 tmp=0, Data: a=10 tmp=0]
Gemt: [Data: a=88 tmp=0, Data: a=10 tmp=0, Data: a=52 tmp=96]

og

Læst: [Data: a=88 tmp=0, Data: a=10 tmp=0, Data: a=52 tmp=0]
Gemt: [Data: a=88 tmp=0, Data: a=10 tmp=0, Data: a=52 tmp=0, Data: a=78 tmp=88]

Læg mærke til, at den transiente variabel tmp ikke bliver husket fra gang til gang.