Nous avons déjà évoqué la thématique de la sérialisation en Java. Cependant, la notion d'externalisation n'a pas encore été mentionnée. Ce sera le sujet de cet article.
L'externalisation repose sur le même principe que la sérialisation. Son objectif principal est de proposer au développeur une possibilité de faire persister un objet Java pour, par exemple, l'échanger entre deux machines différentes sous forme d'un fichier. La différence majeure entre les deux méthodes repose sur la classe implémentée dans cette tâche. Le processus de l'externalisation implémente l'interface java.io.Externalizalbe. Nous allons constater ceci sur cet exemple :
import java.io.Externalizable; import java.io.ObjectOutput; import java.io.ObjectInput; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.FileOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectStreamField; import java.io.OptionalDataException; public class ExternalizablePerso { public static void main(String[] args) { ExternalizablePerso stream = new ExternalizablePerso(); try { stream.writeObjectToFile(); } catch (IOException e) { System.out.println("An error occured on writing object into file " + e.getMessage()); } try { stream.readObjectFromFile(); } catch (Exception e) { System.out.println("An error occured on getting object from file " + e.getMessage()); } } private void readObjectFromFile() throws Exception { ObjectInputStream input = null; try { input = new ObjectInputStream(new FileInputStream("user.externalized")); User user = (User) input.readObject(); System.out.println("Found User object :" + user.toString()); System.out.println("User can access to this page ? " + user.hasAccess()); } finally { if (input != null) input.close(); } } private void writeObjectToFile() throws IOException { ObjectOutputStream output = null; try { output = new ObjectOutputStream(new FileOutputStream("user.externalized")); output.writeObject(new User("administrator", "mod")); } finally { if (output != null) { output.close(); System.out.println("File was correctly saved as user.externalized"); } } } } class User implements Externalizable { protected String[] codes = {"admin", "mod"}; protected String code; protected String login; protected boolean hasAccess; public User() { System.out.println("Constructor called"); } public User(String c, String l) { code = c; login = l; } public void writeExternal(ObjectOutput out) throws IOException { out.writeUTF(code); out.writeUTF(login); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { code = in.readUTF(); login = in.readUTF(); if (login.equals("administrator") && !code.equals("admin")) { hasAccess = false; } } public boolean hasAccess() { return hasAccess; } public String toString() { return "User objetct : login="+login+",code="+code; } }
A la suite de l'exécution du code on verra sur l'écran :
File was correctly saved as user.externalized Constructor called Found User object :User objetct : login=mod,code=administrator User can access to this page ? false
Si l'on compare le code à celui écrit dans l'article consacré à la serialisation en Java, on remarquera que les méthodes writeObject() et readObject() ont été respectivement remplacées par writeExternal() et readExternal(). Le corps de ces deux méthodes se charge de traduire les attributs de la classe User en un format lisible pour la lecture.
Quelles différences entre serializable et externalizable en Java ?
Si tout est pareil, pourqoui alors préférer l'externalisation à la serialisation ? Tout d'abord, le fichier externalisé est plus petit que celui obtenu grâce à la sérialisation. Dans notre cas la différence est marquante. Le fichier généré par l'externalisation pèse 48 octets tandis que celui serialisé 207 octets.
En plus, la présence des méthodes d'écriture et de lecture (writeExternal() et readExternal()) est obligatoire pour une classe implémentant l'interface Externalizable. Cela veut dire que le développeur est obligé de déterminer quoi et comment sera exporté. En ce qui concerne la sérialisation, la présence des méthodes d'écriture et de lecture (writeObject() et readObject()) n'est pas obligatoire. Cela peut causer par exemple les différences au niveau de la taille du fichier exporté.
Cependant, ce dernier avantage est en même temps un inconvenient de l'externalisation. En fait avec chaque changement dans la classe exportée on devra s'occuper de l'externalisation et vérifier si aucune modification ne doit pas y être apportée. Cette problématique ne se pose pas dans le cas d'une implémentation de l'interface Serializable sans méthodes d'écriture et de lecture personnalisées.
Présence des méthodes writeExternal et readExternal eeequi s'occupent de traduire l'objet en une chaîne de caractères compréhensible par deux JVM.
http://www.techartifact.com/blogs/2009/06/serialization-vs-externalization.htmlL'utilisation de ces deux méthodes n'est pas obligée dans l'interface Serializable. On peut faire l'appel, mais on n'a pas besoin de les personnaliser (à checker dans JAvadoc)
Externalisation sera plus performante si est correctement implémentée. C'est le développeur qui contrôle ce qui doit être serializé et comment.
Par contre, l'externalisation perd la flexibilité. Une fois la classe serialisée modifiée, il faut revoir la méthode d'externalisation pour être sûr que rien n'a été cassé (à checker si cela s'applique aussi à Serializable)
http://geekexplains.blogspot.fr/2008/06/diff-between-externalizable-and.htmlreadExternal et writeExternal remplacent readObjet et writeObject de l'interface Serializable.