Que signifie Serialisable?

Que signifie exactement pour qu'une classe Serializable en Java? Ou, en général, d'ailleurs...

107
demandé sur 4rchit3ct 2010-08-07 13:36:08

10 réponses

Sérialisation est la persistance d'un objet à partir de la mémoire à une séquence de bits, par exemple pour l'enregistrement sur le disque. La desérialisation est la lecture opposée des données du disque pour hydrater / créer un objet.

dans le contexte de votre question, c'est une interface qui si implémentée dans une classe, cette classe peut automatiquement être sérialisée et désérialisée par différents sérialiseurs.

109
répondu Oded 2016-09-13 14:22:57

cela signifie que les instances de la classe peuvent être transformées en un byte-stream (par exemple, être sauvegardées dans un fichier) puis reconverties en classes à nouveau. Ce rechargement pourrait se produire dans une autre instance du programme, ou même sur une autre machine. La sérialisation (dans n'importe quelle langue) implique toutes sortes de problèmes, cependant, surtout quand vous avez des références à d'autres objets à l'intérieur du serialisable.

34
répondu David 2010-08-07 09:39:07

Bien que la plupart des utilisateurs ont déjà donné la réponse, mais je voudrais ajouter un exemple pour ceux qui en ont besoin pour expliquer l'idée:

disons que vous avez une personne de classe comme le suivant:

public class Person implements java.io.Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public String firstName;
    public String lastName;
    public int age;
    public String address;

    public void play() {
        System.out.println(String.format(
                "If I win, send me the trophy to this address: %s", address));
    }
    @Override
    public String toString() {
        return String.format(".....Person......\nFirst Name = %s\nLast Name = %s", firstName, lastName);
    }
}

et ensuite vous créez un objet comme ceci:

Person william = new Person();
        william.firstName = "William";
        william.lastName = "Kinaan";
        william.age = 26;
        william.address = "Lisbon, Portugal";

vous pouvez sérialiser cet objet à de nombreux flux. Je ferai cela à deux courants:

Sérialisation pour sortie standard:

public static void serializeToStandardOutput(Person person)
            throws IOException {
        OutputStream outStream = System.out;
        ObjectOutputStream stdObjectOut = new ObjectOutputStream(outStream);
        stdObjectOut.writeObject(person);
        stdObjectOut.close();
        outStream.close();
    }

Sérialisation d'un fichier:

public static void serializeToFile(Person person) throws IOException {
        OutputStream outStream = new FileOutputStream("person.ser");
        ObjectOutputStream fileObjectOut = new ObjectOutputStream(outStream);
        fileObjectOut.writeObject(person);
        fileObjectOut.close();
        outStream.close();
    }

puis:

Désérialiser à partir d'un fichier:

public static void deserializeFromFile() throws IOException,
            ClassNotFoundException {
        InputStream inStream = new FileInputStream("person.ser");
        ObjectInputStream fileObjectIn = new ObjectInputStream(inStream);
        Person person = (Person) fileObjectIn.readObject();
        System.out.println(person);
        fileObjectIn.close();
        inStream.close();
    }
33
répondu William Kinaan 2015-08-24 12:56:04
La sérialisation

consiste à sauvegarder l'état actuel d'un objet dans un flux, et à restaurer un objet équivalent à partir de ce flux. Le flux fonctionne comme un conteneur pour l'objet

10
répondu Jigar Joshi 2010-08-07 09:47:40

Voici une explication détaillée de la sérialisation : (mon propre blog)

Sérialisation:

Sérialisation est le processus de sérialisation de l'état d'un objet est représentée et stockées sous la forme d'une séquence d'octets. Ceci peut être stocké dans un fichier. Le processus pour lire l'état de l'objet à partir du fichier et le restaurer est appelé désérialisation.

Quel est le besoin de Sérialisation?

dans l'architecture moderne, il est toujours nécessaire de stocker l'état de l'objet et de le récupérer. Par exemple, dans Hibernate, pour stocker un objet, nous devrions rendre la classe Serialisable. Ce qu'il fait, c'est qu'une fois que l'état de l'objet est sauvegardé sous forme d'octets, il peut être transféré vers un autre système qui peut alors lire à partir de l'état et récupérer la classe. L'état de l'objet peut partir d'une base de données ou une autre jvm ou à partir d'un autre composant. Avec l'aide de la Sérialisation, nous pouvons récupérer l'état de l'Objet.

exemple de Code et explication:

d'abord jetons un oeil à la classe D'article:

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

dans le code ci-dessus, on peut voir que article class implements Serialisable .

C'est l'interface qui permet à une classe d'être serializable.

maintenant nous pouvons voir une variable appelée serialVersionUID est initialisé à la variable longue. Ce nombre est calculé par le compilateur en fonction de l'état de la classe et les attributs de classe. C'est le numéro qui va aider à la jvm d'identifier l'état d'un objet lorsqu'il lit l'état de l'objet à partir d'un fichier.

pour cela, nous pouvons jeter un oeil à la Documentation officielle Oracle:

l'exécution de la sérialisation s'associe à chaque classe sérialisable a numéro de version, appelé "serialVersionUID", qui est utilisé la désérialisation pour vérifier que l'expéditeur et le destinataire d'un sérialisé objet chargé des classes pour l'objet qui sont compatibles avec le respect de la sérialisation. Si le récepteur a chargé une classe pour objet qui a une versionsuide serialdifférente de celle de l'objet la classe correspondante de l'expéditeur, puis la désérialisation résultera en un InvalidClassException. Une classe sérialisable peut déclarer ses propres serialVersionUID explicitement en déclarant un champ nommé "serialVersionUID" qui doit être statique, final, et de type long: Tout-modificateur d'accès final statique long serialVersionUID = 42L; si a la classe serialisable ne déclare pas explicitement un identifiant serialVersionUID, ensuite, l'exécution de la sérialisation calculera une valeur par défaut serialVersionUID de la valeur pour que la classe de base sur les différents aspects de la classe, comme décrit dans le Java (TM) Sérialisation Des Objets Spécification. Cependant, il est fortement recommandé que tous les les classes serialisable déclarent explicitement les valeurs serialVersionUID, puisque le calcul serialVersionUID par défaut est très sensible à la classe des détails qui peuvent varier selon les implémentations du compilateur, et peuvent ainsi, de manière inattendue pendant InvalidClassExceptions désérialisation. Par conséquent, pour garantir uneversionssérieuse cohérente la valeur de différentes implémentations de compilateurs java, serializable class doit déclarer une valeur explicite serialVersionUID. Il est également il est fortement conseillé que les déclarations explicites de versionsériellesuides utilisent privé modificateur si possible, étant donné que ces déclarations s'appliquent uniquement à les champs déclarant immédiatement classe--serialVersionUID ne sont pas utile comme membres hérités.

si vous avez remarqué qu'il y a un autre mot clé que nous avons utilisé qui est transitoire .

Si un champ n'est pas sérialisable, il doit être marqué transitoire. Ici, nous avons marqué le itemCostPrice comme transitoire et ne veulent pas qu'il soit écrit dans un dossier

voyons maintenant comment écrire l'état d'un objet dans le fichier et ensuite le lire à partir de là.

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

ci-dessus, nous pouvons voir un exemple de sérialisation et de désérialisation d'un objet.

Pour cela nous avons utilisé deux classes. Pour en sérialisant l'objet, nous avons utilisé ObjectOutputStream. Nous avons utilisé la méthode writeObject pour écrire l'objet dans le fichier.

pour la Desérialisation nous avons utilisé ObjectInputStream qui lit à partir de l'objet du fichier. Il utilise readObject pour lire les données de l'objet à partir du fichier.

la sortie du code ci-dessus serait comme:

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

Avis itemCostPrice de l'objet désérialisé est nul comme il n'a pas été écrit.

9
répondu Pritam Banerjee 2017-04-26 00:11:00

Serializable est appelé comme une interface, mais plus comme un drapeau pour le compilateur. Il dit que cet objet peut être sauvé. Toutes les variables d'instance des objets, à l'exception d'aucun objet serialisable et de ceux qui marquent volatile, seront sauvegardées.

Imaginez que votre application peut changer de couleur en option, sans garder ce paramètre externe, vous auriez besoin de changer la couleur à chaque fois que vous l'exécutez.

5
répondu AphexMunky 2010-08-07 09:40:18
La sérialisation

est une technique pour stocker ou écrire les objets et les données dans des fichiers. En utilisant les classes ObjectOutputStream et FileOutputStream . Ces classes ayant leurs méthodes spécifiques pour persister les objets. comme writeObject();

pour une explication claire avec des chiffres . voir ici pour plus d'information

4
répondu Mdhar9e 2012-01-13 09:10:27

à présenter d'un autre point de vue. La sérialisation est une sorte d'interface appelée "interface marqueur". Une interface marqueur est une interface qui ne contient aucune déclaration de méthode, mais désigne simplement (ou" marque") une classe qui implémente l'interface comme ayant certains biens. Si vous comprenez le polymorphisme, cela aura beaucoup de sens. Dans le cas de L'interface de marqueur sérialisable, L'ObjectOutputStream.la méthode write(Object) échouera si son argument n'implémente pas interface. C'est une erreur potentielle en java, ça aurait pu être ObjectOutputStream.Ecrire (sérialisable)

Hautement Recommandé : la Lecture de l'Article 37 de la Effective Java par Joshua Bloch pour en savoir plus.

2
répondu nanospeck 2014-06-02 09:49:52

Sérialisation: l'Écriture de l'État de l'Objet pour le Fichier/Réseau ou n'importe où. ( Moyenne d'Objet Java pris en charge forme de Fichier pris en charge Forme de Réseau ou de Forme pris en charge )

la Désérialisation: la Lecture de l'État de l'Objet à partir d'un Fichier/Réseau ou n'importe où. ( Moyenne de Fichier/Soutenus par le Réseau forme pour Objet Java Forme pris en charge )

1
répondu Asif Mushtaq 2015-10-25 18:48:51

juste pour ajouter aux autres réponses et en ce qui concerne la généralité. La sérialisation est parfois appelée archivage, par exemple dans Objective-C.

0
répondu Greg Sexton 2010-08-07 11:53:28