Les champs d'une classe sérialisable doivent eux-mêmes être sérialisables ou transitoires même si la classe n'est jamais explicitement sérialisée ou désérialisée. En effet, sous charge, la plupart des frameworks d'application J2EE vident les objets sur le disque, et un objet prétendument sérialisable avec des données membres non transitoires et non sérialisables pourrait provoquer des plantages du programme et ouvrir la porte aux attaquants.
Cette règle soulève un problème sur les champs non sérialisables et sur les champs de collection lorsqu'ils ne sont pas privés (car ils pourraient se voir attribuer des valeurs non sérialisables en externe) et lorsqu'ils se voient attribuer des types non sérialisables au sein de la classe.
Exemple de code non conforme
public class Address {
//...
}
public class Person implements Serializable {
private static final long serialVersionUID = 1905122041950251207L;
private String name;
private Address address; // Noncompliant; Address isn't serializable
}
Lorsqu'un objet est sérialisé, selon les règles de sérialisation par défaut de Java, tous les membres de l'objet doivent être sérialisés. C'est-à-dire que ces classes doivent implémenter Serialisable.
Vous avez donc deux façons de le modifier. L'une consiste à implémenter l'interface Serialisable dans Address, et l'autre consiste à ajouter une marque
transient
au membre d'adresse dans Person afin que le membre ne soit pas sérialisé.Si le membre de l'adresse doit être sérialisé, la classe Address doit également implémenter l'interface Serialisisable.
Si le membre de l'adresse n'a pas besoin d'être sérialisé, vous pouvez ajouter le mot-clé transient, le membre de l'adresse ne sera alors pas sérialisé et la valeur sera nulle. Comme suit :
Bien sûr, il existe d'autres moyens :
Par exemple, implémenter l'interface Externalalisable et remplacer les méthodes readExternal(ObjectInput in) et writeExternal(ObjectOutput out).
Il existe également une implémentation alternative de la méthode d'interface Externalalisable, ou implémentez l'interface Serialalisable, en ajoutant les méthodes writeObject(ObjectOutputStream obs) et readObject(ObjectInputStream ois).
Répétez-moi pourquoi Address doit implémenter Seriallessly, ou ajouter le mot-clé transient Person pour être sérialisé ?
Jetons d'abord un coup d'œil à l'exception levée en utilisant ObjectOutputStream pour conserver l'objet sans traitement
Regardez ObjectOutputStreamCode source :
On peut voir à partir de cela que si le type d'objet en cours d'écriture est String, Array, Enum ou Seriallessly, il peut être sérialisé, sinon NotSerializingException sera levée. Et lors de la sérialisation d'un objet, non seulement l'objet actuel lui-même sera sérialisé, mais les autres objets référencés par l'objet seront également sérialisés.