¿Qué es la serialización de objetos?

Respuestas:

400

La serialización es la conversión de un objeto a una serie de bytes, de modo que el objeto se pueda guardar fácilmente en un almacenamiento persistente o transmitir a través de un enlace de comunicación. La secuencia de bytes se puede deserializar, convertir en una réplica del objeto original.

TarkaDaal
fuente
16
¿Es esto obligatorio? ¿Debo serializar los datos antes de enviarlos? ¿A qué formato se convierte?
Francisco Corrales Morales
15
@FranciscoCorralesMorales: detrás de escena, todos los datos se serializarán antes de que se envíen por una transmisión. La cantidad que necesita hacer y el formato en el que estará dependen de la plataforma y las bibliotecas que esté utilizando.
TarkaDaal
3
@FranciscoCorralesMorales ¿Cómo lo dices? Quiero decir que estás diciendo que el formato depende de la plataforma y las bibliotecas. Realmente quiero saber el formato.
JAVA
1
¿Es aplicable solo a objetos? ¿Podemos serializar variables (declaradas sin usar objetos)?
Rumado
@Rumado Objects only
anKotliner
395

Puede pensar en la serialización como el proceso de convertir una instancia de objeto en una secuencia de bytes (que puede ser binaria o no dependiendo de la implementación).

Es muy útil cuando desea transmitir datos de un objeto a través de la red, por ejemplo, de una JVM a otra.

En Java, el mecanismo de serialización está integrado en la plataforma, pero debe implementar la interfaz serializable para que un objeto sea serializable.

También puede evitar que algunos datos en su objeto se serialicen marcando el atributo como transitorio .

Finalmente, puede anular el mecanismo predeterminado y proporcionar el suyo propio; Esto puede ser adecuado en algunos casos especiales. Para hacer esto, utiliza una de las funciones ocultas en Java .

Es importante notar que lo que se serializa es el "valor" del objeto, o los contenidos, y no la definición de clase. Por lo tanto, los métodos no están serializados.

Aquí hay una muestra muy básica con comentarios para facilitar su lectura:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

Cuando ejecutamos este programa, se crea el archivo "o.ser" y podemos ver lo que sucedió detrás.

Si cambiamos el valor de: someInteger a, por ejemplo , Integer.MAX_VALUE , podemos comparar la salida para ver cuál es la diferencia.

Aquí hay una captura de pantalla que muestra precisamente esa diferencia:

texto alternativo

¿Puedes ver las diferencias? ;)

Hay un campo adicional relevante en la serialización de Java: el serialversionUID pero supongo que esto ya es demasiado largo para cubrirlo.

OscarRyz
fuente
1
La instancia de @ raam86 es el objeto que se está serializando. Puede pensar en el método principal como un programa separado que crea un objeto de tipoSerializationSample
OscarRyz
2
@ raam86 es la primera instrucción en el método principal: SerializationSample instance = new SerializationSample();luego se crea la salida y se escribe el objeto en esa salida.
OscarRyz
1
Oh. No seguí lo suficientemente cerca. ¡¡Excelente!!
raam86
1
@jacktrades ¿Por qué no lo intentas? Simplemente copie / pegue el ejemplo y vea que se lanza "NotSerializableException" :)
OscarRyz
1
@jacktrades porque a la computadora no se le ha dicho que el objeto puede ser serializado :) ¿qué se entiende por oos?
Chris Bennett
101

Atreverse a responder la pregunta de hace 6 años, agregando solo una comprensión de muy alto nivel para las personas nuevas en Java

¿Qué es la serialización?

Convertir un objeto a bytes

¿Qué es la deserialización?

Convertir bytes nuevamente a un objeto (Deserialización).

¿Cuándo se usa la serialización?

Cuando queremos persistir el objeto. Cuando queremos que el objeto exista más allá de la vida útil de la JVM.

Ejemplo del mundo real:

Cajero automático: cuando el titular de la cuenta intenta retirar dinero del servidor a través del cajero automático, la información del titular de la cuenta, como los detalles del retiro, se serializará y se enviará al servidor donde los detalles se deserializan y se utilizan para realizar operaciones.

Cómo se realiza la serialización en Java.

  1. java.io.SerializableInterfaz de implementación (interfaz de marcador, por lo que no hay ningún método para implementar).

  2. Persistir el objeto: utilice la java.io.ObjectOutputStreamclase, una secuencia de filtro que es una envoltura alrededor de una secuencia de bytes de nivel inferior (para escribir objetos en sistemas de archivos o transferir un objeto aplanado a través de un cable de red y reconstruido en el otro lado).

    • writeObject(<<instance>>) - para escribir un objeto
    • readObject() - para leer un objeto serializado

Recuerda:

Cuando serializa un objeto, solo se guardará el estado del objeto, no el archivo de clase o los métodos del objeto.

Cuando serializa un objeto de 2 bytes, ve un archivo serializado de 51 bytes.

Pasos de cómo se serializa y deserializa el objeto.

Respuesta para: ¿Cómo se convirtió al archivo de 51 bytes?

  • Primero escribe los datos mágicos del flujo de serialización (STREAM_MAGIC = "AC ED" y STREAM_VERSION = versión de la JVM).
  • Luego escribe los metadatos de la clase asociada con una instancia (longitud de la clase, el nombre de la clase, serialVersionUID).
  • Luego escribe de forma recursiva los metadatos de la superclase hasta que encuentra java.lang.Object.
  • Luego comienza con los datos reales asociados con la instancia.
  • Finalmente, escribe los datos de los objetos asociados con la instancia a partir de los metadatos en el contenido real.

Si está interesado en obtener información más detallada sobre la serialización de Java, consulte este enlace .

Editar : un buen enlace más para leer.

Esto responderá algunas preguntas frecuentes:

  1. Cómo no serializar ningún campo en clase.
    Respuesta: use palabras clave transitorias

  2. Cuando la clase secundaria se serializa, ¿se serializa la clase primaria?
    Respuesta: No, si un padre no amplía el campo de padres de la interfaz serializable, no se serialice.

  3. Cuando un padre se serializa, ¿se serializa la clase secundaria?
    Respuesta: Sí, por defecto, la clase secundaria también se serializa.

  4. ¿Cómo evitar que la clase infantil se serialice?
    Respuesta: a. Reemplazar el método writeObject y readObject y throw NotSerializableException.

    si. También puede marcar todos los campos como transitorios en la clase secundaria.

  5. Algunas clases de nivel de sistema como Thread, OutputStream y sus subclases y Socket no son serializables.
VdeX
fuente
3
Muchas gracias por esta breve respuesta, fue muy útil.
Nobi
21

La serialización es tomar un objeto "vivo" en la memoria y convertirlo a un formato que pueda almacenarse en algún lugar (por ejemplo, en la memoria, en el disco) y luego "deserializarse" de nuevo en un objeto vivo.

Kent Boogaart
fuente
14

Me gustó la forma en que @OscarRyz presenta. Aunque aquí continúo la historia de serialización que originalmente fue escrita por @amitgupta.

Aunque conocer la estructura de clase del robot y haber serializado los datos, el científico de la Tierra no pudo deserializar los datos que pueden hacer que los robots funcionen.

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

Los científicos de Marte estaban esperando el pago completo. Una vez realizado el pago, los científicos de Marte compartieron el serialversionUID con los científicos de la Tierra. El científico de la Tierra lo estableció en la clase de robot y todo se puso bien.

noquery
fuente
9

Serialización significa objetos persistentes en java. Si desea guardar el estado del objeto y desea reconstruir el estado más adelante (puede estar en otra JVM) se puede utilizar la serialización.

Tenga en cuenta que las propiedades de un objeto solo se guardarán. Si desea resucitar el objeto nuevamente, debe tener el archivo de clase, porque las variables miembro solo se almacenarán y no las funciones miembro.

p.ej:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

El buscador es una interfaz de marcador que marca que su clase es serializable. La interfaz de marcador significa que es solo una interfaz vacía y el uso de esa interfaz notificará a la JVM que esta clase puede hacerse serializable.

Sathesh
fuente
9

Mis dos centavos de mi propio blog:

Aquí hay una explicación detallada de la serialización : (mi propio blog)

Publicación por entregas:

La serialización es el proceso de persistencia del estado de un objeto. Se representa y almacena en forma de una secuencia de bytes. Esto se puede almacenar en un archivo. El proceso para leer el estado del objeto del archivo y restaurarlo se llama deserialización.

¿Cuál es la necesidad de la serialización?

En la arquitectura moderna, siempre es necesario almacenar el estado del objeto y luego recuperarlo. Por ejemplo, en Hibernate, para almacenar un objeto debemos hacer que la clase Serializable. Lo que hace es que una vez que el estado del objeto se guarda en forma de bytes, se puede transferir a otro sistema que luego puede leer el estado y recuperar la clase. El estado del objeto puede provenir de una base de datos o una jvm diferente o de un componente separado. Con la ayuda de la serialización podemos recuperar el estado del objeto.

Código de ejemplo y explicación:

Primero echemos un vistazo a la clase de artículo:

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;
        }
}

En el código anterior se puede ver que la clase Item implementa Serializable .

Esta es la interfaz que permite que una clase sea serializable.

Ahora podemos ver que una variable llamada serialVersionUID se inicializa en Variable larga. El compilador calcula este número basándose en el estado de la clase y los atributos de la clase. Este es el número que ayudará a la jvm a identificar el estado de un objeto cuando lee el estado del objeto del archivo.

Para eso podemos echar un vistazo a la documentación oficial de Oracle:

El tiempo de ejecución de serialización asocia a cada clase serializable un número de versión, llamado serialVersionUID, que se utiliza durante la deserialización para verificar que el emisor y el receptor de un objeto serializado hayan cargado clases para ese objeto que son compatibles con respecto a la serialización. Si el receptor ha cargado una clase para el objeto que tiene un serialVersionUID diferente al de la clase del remitente correspondiente, la deserialización dará como resultado una InvalidClassException. Una clase serializable puede declarar explícitamente su propio serialVersionUID declarando un campo llamado "serialVersionUID" que debe ser estático, final y de tipo largo: CUALQUIER MODIFICADOR DE ACCESO estático final largo serialVersionUID = 42L; Si una clase serializable no declara explícitamente un serialVersionUID, entonces el tiempo de ejecución de serialización calculará un valor predeterminado serialVersionUID para esa clase en función de varios aspectos de la clase, como se describe en la Especificación de serialización de objetos Java (TM). Sin embargo, se recomienda encarecidamente que todas las clases serializables declaren explícitamente los valores serialVersionUID, ya que el cálculo predeterminado serialVersionUID es muy sensible a los detalles de la clase que pueden variar según las implementaciones del compilador y, por lo tanto, pueden dar lugar a inesperadas InvalidClassExceptions durante la deserialización. Por lo tanto, para garantizar un valor de serialVersionUID consistente en diferentes implementaciones del compilador de Java, una clase serializable debe declarar un valor de serialVersionUID explícito. También se recomienda encarecidamente que las declaraciones explícitas serialVersionUID utilicen el modificador privado cuando sea posible,

Si ha notado que hay otra palabra clave que hemos usado que es transitoria .

Si un campo no es serializable, debe marcarse como transitorio. Aquí marcamos el itemCostPrice como transitorio y no queremos que se escriba en un archivo

Ahora echemos un vistazo a cómo escribir el estado de un objeto en el archivo y luego leerlo desde allí.

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();
        }
     }
}

En lo anterior podemos ver un ejemplo de serialización y deserialización de un objeto.

Para eso usamos dos clases. Para serializar el objeto, hemos utilizado ObjectOutputStream. Hemos utilizado el método writeObject para escribir el objeto en el archivo.

Para la deserialización, hemos utilizado ObjectInputStream que lee del objeto del archivo. Utiliza readObject para leer los datos del objeto del archivo.

El resultado del código anterior sería como:

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]

Tenga en cuenta que itemCostPrice del objeto deserializado es nulo ya que no se escribió.

Ya hemos discutido los conceptos básicos de la serialización Java en la parte I de este artículo.

Ahora discutamos profundamente y cómo funciona.

Primero comencemos con el serialversionuid.

El serialVersionUID se utiliza como un control de versión en una clase Serializable.

Si no declara explícitamente un serialVersionUID, JVM lo hará por usted automáticamente, en función de varias propiedades de la clase Serializable.

Algoritmo de Java para calcular serialversionuid (Lea más detalles aquí)

  1. El nombre de la clase.
    1. Los modificadores de clase escritos como un entero de 32 bits.
    2. El nombre de cada interfaz ordenado por nombre.
    3. Para cada campo de la clase ordenado por nombre de campo (excepto campos privados estáticos y transitorios privados: El nombre del campo. Los modificadores del campo escritos como un entero de 32 bits. El descriptor del campo.
    4. Si existe un inicializador de clase, escriba lo siguiente: El nombre del método,.
    5. El modificador del método, java.lang.reflect.Modifier.STATIC, escrito como un entero de 32 bits.
    6. El descriptor del método, () V.
    7. Para cada constructor no privado ordenado por nombre y firma del método: El nombre del método,. Los modificadores del método escrito como un entero de 32 bits. El descriptor del método.
    8. Para cada método no privado ordenado por nombre y firma del método: El nombre del método. Los modificadores del método escrito como un entero de 32 bits. El descriptor del método.
    9. El algoritmo SHA-1 se ejecuta en la secuencia de bytes producidos por DataOutputStream y produce cinco valores de 32 bits sha [0..4]. El valor hash se ensambla a partir del primer y segundo valor de 32 bits del resumen del mensaje SHA-1. Si el resultado del resumen del mensaje, las cinco palabras de 32 bits H0 H1 H2 H3 H4, está en una matriz de cinco valores int llamados sha, el valor hash se calcularía de la siguiente manera:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Algoritmo de serialización de Java

El algoritmo para serializar un objeto se describe a continuación:
1. Escribe los metadatos de la clase asociada con una instancia.
2. Escribe de forma recursiva la descripción de la superclase hasta que encuentre java.lang.object .
3. Una vez que termina de escribir la información de metadatos, comienza con los datos reales asociados con la instancia. Pero esta vez, comienza desde la superclase más alta.
4. Escribe de forma recursiva los datos asociados con la instancia, comenzando desde la superclase mínima hasta la clase más derivada.

Cosas a tener en cuenta:

  1. Los campos estáticos en una clase no se pueden serializar.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
  2. Si serialversionuid es diferente en la clase de lectura, arrojará una InvalidClassExceptionexcepción.

  3. Si una clase implementa serializable, todas sus subclases también serán serializables.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
  4. Si una clase tiene una referencia de otra clase, todas las referencias deben ser serializables, de lo contrario no se realizará el proceso de serialización. En tal caso, NotSerializableException se lanza en tiempo de ejecución.

P.ej:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}
Pritam Banerjee
fuente
1
'La serialización es el proceso de serializar el estado de un objeto representado y almacenado en forma de una secuencia de bytes' no tiene sentido. Si el serialVersionUIDes diferente arrojará un InvalidClassException, no un ClassCastException. No es necesario desperdiciar todo ese espacio respetando la serialVersionUIDcomputación. La documentación se cita, con una extensión excesiva, pero no está vinculada ni se cita adecuadamente. Demasiada pelusa aquí y demasiados errores.
Marqués de Lorne
'La serialización es el proceso de serialización' no tiene sentido.
Marqués de Lorne
6

La serialización es el proceso de convertir el estado de un objeto en bits para que pueda almacenarse en un disco duro. Cuando deserializa el mismo objeto, conservará su estado más adelante. Le permite recrear objetos sin tener que guardar las propiedades de los objetos a mano.

http://en.wikipedia.org/wiki/Serialization

Queso danés
fuente
"... para que pueda almacenarse en un disco duro". O transferido a través de un protocolo binario.
Jim Anderson el
4

Serialización de objetos Java

ingrese la descripción de la imagen aquí

Serializationes un mecanismo para transformar un gráfico de objetos Java en una matriz de bytes para almacenamiento ( to disk file) o transmisión (across a network ), luego mediante deserialización , podemos restaurar el gráfico de objetos. Los gráficos de objetos se restauran correctamente utilizando un mecanismo para compartir referencias. Pero antes de almacenar, verifique si serialVersionUID de input-file / network y .class file serialVersionUID son iguales. Si no, tira un java.io.InvalidClassException.

Cada clase versionada debe identificar la versión de clase original para la cual es capaz de escribir secuencias y de la que puede leer. Por ejemplo, una clase versionada debe declarar:

sintaxis serialVersionUID

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUID es esencial para el proceso de serialización. Pero es opcional para el desarrollador agregarlo al archivo fuente de Java. Si no se incluye un serialVersionUID, el tiempo de ejecución de serialización generará un serialVersionUID y lo asociará con la clase. El objeto serializado contendrá este serialVersionUID junto con otros datos.

Nota : se recomienda encarecidamente que todas las clases serializables declaren explícitamente un serialVersionUID,since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations , pueden dar lugar a conflictos inesperados de serialVersionUID durante la deserialización, lo que hace que la deserialización falle.

Inspección de clases serializables

ingrese la descripción de la imagen aquí


Un objeto Java solo es serializable. si una clase o cualquiera de sus superclases implementa la interfaz java.io.Serializable o su subinterfaz, java.io.Externalizable .

  • Una clase debe implementar la interfaz java.io.Serializable para serializar su objeto con éxito. Serializable es una interfaz de marcador y se utiliza para informar al compilador que la clase que lo implementa tiene que agregar un comportamiento serializable. Aquí Java Virtual Machine (JVM) es responsable de su serialización automática.

    Palabra clave transitoria: java.io.Serializable interface

    Mientras se serializa un objeto, si no queremos que ciertos miembros de datos del objeto se serialicen, podemos usar el modificador transitorio. La palabra clave transitoria evitará que ese miembro de datos se serialice.

    • El proceso de serialización ignora los campos declarados como transitorios o estáticos.

    TRANSITORIO Y VOLÁTIL

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
  • La implementación de la interfaz Externalizable permite que el objeto asuma un control completo sobre el contenido y el formato de la forma serializada del objeto. Los métodos de la interfaz Externalizable, writeExternal y readExternal, se llaman para guardar y restaurar el estado de los objetos. Cuando los implementa una clase, pueden escribir y leer su propio estado utilizando todos los métodos de ObjectOutput y ObjectInput. Es responsabilidad de los objetos manejar cualquier versión que ocurra.

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
  • Solo los objetos que admiten la interfaz java.io.Serializable o java.io.Externalizable pueden ser written to/read from streams. La clase de cada objeto serializable se codifica incluyendo el nombre de la clase y la firma de la clase, los valores de los campos y matrices del objeto, y el cierre de cualquier otro objeto referenciado desde los objetos iniciales.

Ejemplo serializable para archivos

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Ejemplo serializable a través de la red

Objeto de distribución el estado del través de diferentes espacios de direcciones, ya sea en diferentes procesos en la misma computadora, o incluso en varias computadoras conectadas a través de una red, pero que trabajan juntas al compartir datos e invocar métodos.

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@ver

Yash
fuente
1
Cuando agrega una respuesta a una pregunta de seis años que ya tiene varias respuestas muy buenas, debe hacerlo mucho mejor que una cacofonía de errores ortográficos.
Marqués de Lorne
@ejp Downvoting es la herramienta para expresar tu opinión negativa. Ser ofensivo y casi grosero es inaceptable.
Konstantinos Chertouras
1
@KonstantinosChertouras Dar razones para el voto negativo es útil para el afiche, y esas son mis razones, les guste o no como quieran.
Marqués de Lorne
También debe evitar errores como afirmar que la serialización tiene un propósito de seguridad. No lo hace.
Marqués de Lorne
@EJP He actualizado mi publicación, corregido que la serialización no es para fines de seguridad, pero se usa para transformar el estado de un Objeto en cualquier Almacenamiento y para recuperar el estado original de un objeto usando SUID a través del mecanismo de deserialización. JVM to JVM
Yash
3

La serialización es el proceso de guardar un objeto en un medio de almacenamiento (como un archivo o un búfer de memoria) o transmitirlo a través de una conexión de red en forma binaria. Los objetos serializados son independientes de JVM y cualquier JVM puede volver a serializarlos. En este caso, el estado de los objetos Java "en memoria" se convierte en un flujo de bytes. Este tipo de archivo no puede ser entendido por el usuario. Es un tipo especial de objeto, es decir, reutilizado por la JVM (Java Virtual Machine). Este proceso de serialización de un objeto también se llama desinflar o ordenar un objeto.

El objeto a serializar debe implementar la java.io.Serializableinterfaz. El mecanismo de serialización predeterminado para un objeto escribe la clase del objeto, la firma de la clase y los valores de todos los campos no transitorios y no estáticos.

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutputinterfaz extiende la DataOutputinterfaz y agrega métodos para serializar objetos y escribir bytes en el archivo. La interfaz se ObjectOutputStreamextiende java.io.OutputStreame implementa ObjectOutput. Serializa objetos, matrices y otros valores en una secuencia. Así, el constructor de ObjectOutputStreamse escribe como:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

El código anterior se ha utilizado para crear la instancia de la ObjectOutputclase con el ObjectOutputStream( )constructor que toma la instancia de FileOuputStreamcomo parámetro.

La ObjectOutputinterfaz se usa implementando la ObjectOutputStreamclase. El ObjectOutputStreamestá construido para serializar el objeto.

Deserializar un objeto en java

La operación opuesta de la serialización se llama deserialización, es decir, extraer los datos de una serie de bytes se conoce como deserialización, que también se llama inflar o desarmar.

ObjectInputStreamextiende java.io.InputStreame implementa la ObjectInput interfaz. Deserializa objetos, matrices y otros valores de una secuencia de entrada. Así, el constructor de ObjectInputStreamse escribe como:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

El código anterior del programa crea la instancia de la ObjectInputStreamclase para deserializar ese archivo que había sido serializado por la ObjectInputStreamclase. El código anterior crea la instancia utilizando la instancia de la FileInputStreamclase que contiene el objeto de archivo especificado que debe ser deserializado porque el ObjectInputStream()constructor necesita la secuencia de entrada.

Sindu
fuente
2

Devuelva el archivo como un Objeto: http://www.tutorialspoint.com/java/java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }
Ran Adler
fuente
Esto no responde las partes de la pregunta 'qué es' o 'por favor explique'.
Marqués de Lorne
1

| * | Serializar una clase: Convertir un objeto a bytes y bytes nuevamente a objeto (Deserialización).

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

| => La serialización de objetos es el proceso de convertir el estado de un objeto en vapor de bytes.

  • | -> Implemente cuando desee que el objeto exista más allá de la vida útil de la JVM.
  • | -> El objeto serializado se puede almacenar en la base de datos.
  • | -> Los seres serializables no pueden ser leídos y entendidos por humanos por lo que podemos lograr seguridad.

| => Object-Deserialization es el proceso de obtener el estado de un objeto y almacenarlo en un objeto (java.lang.Object).

  • | -> Antes de almacenar su estado, comprueba si serialVersionUID form input-file / network y .class file serialVersionUID son iguales.
    & nbsp & nbsp Si no arroja java.io.InvalidClassException.

| => Un objeto Java solo es serializable, si su clase o alguna de sus superclases

  • implementa la interfaz java.io.Serializable o
  • su subinterfaz, java.io.Externalizable.

| => Los campos estáticos en una clase no se pueden serializar.

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

| => Si no desea serializar una variable de una clase, utilice la palabra clave transitoria

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

| => Si una clase implementa serializable, todas sus subclases también serán serializables.

| => Si una clase tiene una referencia de otra clase, todas las referencias deben ser serializables, de lo contrario no se realizará el proceso de serialización. En tal caso,
NotSerializableException se lanza en tiempo de ejecución.

Sujay UN
fuente
0

Ofreceré una analogía para ayudar potencialmente a solidificar el propósito conceptual / practicidad de la serialización / deserialización de objetos .

Me imagino la serialización / deserialización de objetos en el contexto de intentar mover un objeto a través de un drenaje pluvial. El objeto está esencialmente "descompuesto" o serializado en versiones más modulares de sí mismo, en este caso, una serie de bytes , para que se le permita pasar efectivamente a través de un medio. En un sentido computacional, podríamos ver la ruta recorrida por los bytes a través del drenaje pluvial como similar a los bytes que viajan a través de una red. Estamos transmutando nuestro objeto para adaptarnos a un modo de transporte o formato más deseable. El objeto serializado generalmente se almacenará en un archivo binario que luego se puede leer, escribir o ambos.

Quizás una vez que nuestro objeto pueda deslizarse a través del drenaje como una serie descompuesta de bytes, es posible que deseemos almacenar esa representación del objeto como datos binarios dentro de una base de datos o unidad de disco duro. Sin embargo, la conclusión principal es que con la serialización / deserialización, tenemos la opción de dejar que nuestro objeto permanezca en su forma binaria después de ser serializado, o "recuperar" la forma original del objeto realizando la deserialización.

Benjamin Westburg
fuente