¿Qué se entiende por "serialización de objetos"? ¿Puedes explicarlo con algunos ejemplos?
¿Qué se entiende por "serialización de objetos"? ¿Puedes explicarlo con algunos ejemplos?
Respuestas:
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.
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:
¿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.
SerializationSample
SerializationSample instance = new SerializationSample();
luego se crea la salida y se escribe el objeto en esa salida.
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.
java.io.Serializable
Interfaz de implementación (interfaz de marcador, por lo que no hay ningún método para implementar).
Persistir el objeto: utilice la java.io.ObjectOutputStream
clase, 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 serializadoRecuerda:
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?
java.lang.Object
.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:
Cómo no serializar ningún campo en clase.
Respuesta: use palabras clave transitorias
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.
Cuando un padre se serializa, ¿se serializa la clase secundaria?
Respuesta: Sí, por defecto, la clase secundaria también se serializa.
¿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.
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.
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.
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.
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í)
- El nombre de la clase.
- Los modificadores de clase escritos como un entero de 32 bits.
- El nombre de cada interfaz ordenado por nombre.
- 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.
- Si existe un inicializador de clase, escriba lo siguiente: El nombre del método,.
- El modificador del método, java.lang.reflect.Modifier.STATIC, escrito como un entero de 32 bits.
- El descriptor del método, () V.
- 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.
- 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.
- 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:
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";
}
Si serialversionuid es diferente en la clase de lectura, arrojará una InvalidClassException
excepción.
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
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
}
serialVersionUID
es diferente arrojará un InvalidClassException
, no un ClassCastException
. No es necesario desperdiciar todo ese espacio respetando la serialVersionUID
computació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.
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.
Serialization
es 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
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.
+--------------+--------+-------------------------------------+ | 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
JVM to JVM
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.Serializable
interfaz. 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,
ObjectOutput
interfaz extiende la DataOutput
interfaz y agrega métodos para serializar objetos y escribir bytes en el archivo. La interfaz se ObjectOutputStream
extiende java.io.OutputStream
e implementa ObjectOutput
. Serializa objetos, matrices y otros valores en una secuencia. Así, el constructor de ObjectOutputStream
se escribe como:
ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));
El código anterior se ha utilizado para crear la instancia de la ObjectOutput
clase con el ObjectOutputStream( )
constructor que toma la instancia de FileOuputStream
como parámetro.
La ObjectOutput
interfaz se usa implementando la ObjectOutputStream
clase. El ObjectOutputStream
está 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.
ObjectInputStream
extiende java.io.InputStream
e implementa la ObjectInput
interfaz. Deserializa objetos, matrices y otros valores de una secuencia de entrada. Así, el constructor de ObjectInputStream
se escribe como:
ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));
El código anterior del programa crea la instancia de la ObjectInputStream
clase para deserializar ese archivo que había sido serializado por la ObjectInputStream
clase. El código anterior crea la instancia utilizando la instancia de la FileInputStream
clase que contiene el objeto de archivo especificado que debe ser deserializado porque el ObjectInputStream()
constructor necesita la secuencia de entrada.
La serialización es el proceso de convertir un objeto Java en una matriz de bytes y luego volverlo a convertir en objeto nuevamente con su estado preservado. Útil para varias cosas como enviar objetos a través de la red o almacenar en caché cosas en el disco.
Lea más de este breve artículo que explica bastante bien la programación del proceso y luego pase a Serializable javadoc . También puede estar interesado en leer esta pregunta relacionada .
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);
}
}
| * | 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.
| => Object-Deserialization es el proceso de obtener el estado de un objeto y almacenarlo en un objeto (java.lang.Object).
| => Un objeto Java solo es serializable, si su clase o alguna de sus superclases
| => 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.
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.