java - Pourquoi la classe définie dans Serialisable ne peut-elle pas être sérialisée?
欧阳克
欧阳克 2017-06-30 09:56:37
0
2
1184

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
}
欧阳克
欧阳克

温故而知新,可以为师矣。 博客:www.ouyangke.com

répondre à tous(2)
扔个三星炸死你

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é.

typecho

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 :

public class Person implements Serializable {
  private static final long serialVersionUID = 1905122041950251207L;

  private String name;
  private transient Address address;  // Noncompliant; Address isn't serializable
}

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

Exception in thread "main" java.io.NotSerializableException

Regardez ObjectOutputStreamCode source :

/**
     * Underlying writeObject/writeUnshared implementation.
     */
    private void writeObject0(Object obj, boolean unshared)
        throws IOException
    {
            //......
            // remaining cases
            if (obj instanceof String) {
                writeString((String) obj, unshared);
            } else if (cl.isArray()) {
                writeArray(obj, desc, unshared);
            } else if (obj instanceof Enum) {
                writeEnum((Enum<?>) obj, desc, unshared);
            } else if (obj instanceof Serializable) {
                writeOrdinaryObject(obj, desc, unshared);
            } else {
                if (extendedDebugInfo) {
                    throw new NotSerializableException(
                        cl.getName() + "\n" + debugInfoStack.toString());
                } else {
                    throw new NotSerializableException(cl.getName());
                }
            }
        } finally {
            depth--;
            bout.setBlockDataMode(oldMode);
        }
    }

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.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!