Programmieren mit Java IIhttp://sol.cs.hm.edu/4129Inhaltsverzeichnis
2. Serialisierung2.3 JavaBeans
2.3.7 Neue Serialisierer
Einbau eigener Serialisierer
XMLEncoder arbeitet auch mit neuen, selbst definierten Serialisierern. Zum Beispiel sind in der weiter vorne definierten Klasse PlayersBean.java vier Methoden erforderlich, um die indexierte Property players getreu Konvention umzusetzen. Diese Bean-Klasse weist Eigenschaften auf, die zum Teil etwas störend sind:
Wegfall der Beans-Konventionen
Die folgende Klasse Players räumt mit diesen Problemen auf und bietet eine kompaktere und sicherere Schnittstelle. Sie folgt allerdings überhaupt nicht mehr den eingangs vorgestellten Beans-Konventionen.
import java.util.*;



public class Players {

private final List<Player> players = new ArrayList<>();



public List<Player> getPlayers() {

return Collections.unmodifiableList(players);

}



public Players addPlayer(Player player) {

players.add(player);

return this;

}

}

Players.java: Klasse mit einer Liste von Spielern.
Mit einem passenden Serialisierer kann auch diese Klasse verwendet werden. Der Serialisierer muss allerdings dafür sorgen, dass ein Players-Objekt bei der Deserialisierung durch addPlayer-Aufrufe mit deserialisierten Player-Objekten gefüllt wird. Dazu wird von DefaultPersistenceDelegate eine neue Klasse PlayersPersistenceDelegate abgeleitet, die die Methode initialize redefiniert. initialize legt fest, wie ein Objekt deserialisiert wird. Die Implementierung in der Basisklasse DefaultPersistenceDelegate sucht nach Methoden gemäß Beans-Konventionen, findet jetzt aber nichts mehr. Der Aufruf super.initialize hat also nur noch einen Default-Konstruktoraufruf zur Folge. Anschließend wird in einer Schleife für jeden Player ein Statement-Objekt erzeugt, das einen Aufruf der Methode addPlayer repräsentiert.[29]
Dieser nur für Players zuständige Serialisierer kann als Objektvariable in der Klasse Players selbst definiert werden. Die Implementierung vereinfacht sich dadurch noch ein wenig.
import java.beans.*;



public class PlayersPersistenceDelegate extends DefaultPersistenceDelegate {

protected void initialize(Class type, Object old, Object noo, Encoder encoder) {

super.initialize(type, old, noo, encoder);

Players players = (Players)old;

for(Player player: players.getPlayers()) {

Statement statement = new Statement(old, "addPlayer", new Object[] {player});

encoder.writeStatement(statement);

}

}

}

PlayersPersistenceDelegate.java: Serialisierer für eine Klasse mit einer Liste von Spielern.
Registrieren des neuen Serialisierers
Bei der Serialisierung wird ein PlayersPersistenceDelegate als Serialisierer für die Klasse Players registriert und dann automatisch vom XMLEncoder benutzt.
import java.beans.*;

import java.io.*;



public class PlayersIO {

public static void main(String... args) throws IOException {

Players players;

if(args.length == 1)

try(OutputStream output = new FileOutputStream(args[0]);

XMLEncoder encoder = new XMLEncoder(output)) {

encoder.setPersistenceDelegate(Player.class,

new DefaultPersistenceDelegate(new String[] {

"name"

}));



Player max = new Player("Max");

max.setScore(5);



Player moritz = new Player("Moritz");

moritz.setScore(3);



players = new Players().addPlayer(max).addPlayer(moritz);

encoder.writeObject(players);

}

else

try(InputStream in = new FileInputStream(args[0]);

XMLDecoder decoder = new XMLDecoder(in)) {

players = (Players)decoder.readObject();

}

System.out.println(players);

}

}

PlayersIO.java: Ersatz des Default-Serialisierers durch einen neuen Serialisierer.
Wieder ist keine Änderung an der Deserialisierung nötig.