java - serializar - tipos de serializacion
¿Qué es la serialización de objetos? (14)
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);
}
}
¿Qué se entiende por "serialización de objetos"? ¿Puedes por favor explicarlo con algunos ejemplos?
La serialización consiste en tomar un objeto "vivo" en la memoria y convertirlo a un formato que se pueda almacenar en algún lugar (p. Ej., En la memoria, en el disco) y luego "deserializarse" nuevamente en un objeto vivo.
La serialización es el proceso de convertir el estado de un objeto a bits para que pueda almacenarse en un disco duro. Cuando deserializa el mismo objeto, retendrá su estado más adelante. Te permite recrear objetos sin tener que guardar las propiedades de los objetos a mano.
La serialización es el proceso de convertir un objeto Java en una matriz de bytes y luego volver a convertirlo en un objeto con su estado conservado. Útil para varias cosas como enviar objetos a través de la red o almacenar en caché en el disco.
Lea más de este breve artículo que explica la programación del proceso bastante bien y luego vaya a Serializable javadoc . También puede estar interesado en leer esta pregunta relacionada .
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 pueden ser re-serializados por cualquier JVM. 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 serializar un objeto también se denomina desinflar o ordenar un objeto.
El objeto a ser serializado debe implementar la interfaz java.io.Serializable
. 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 ObjectOutput
extiende la interfaz DataOutput
y agrega métodos para serializar objetos y escribir bytes en el archivo. ObjectOutputStream
extiende java.io.OutputStream
e implementa la interfaz ObjectOutput
. Se serializan objetos, matrices y otros valores a 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 clase ObjectOutput
con el constructor ObjectOutputStream( )
que toma la instancia de FileOuputStream
como un parámetro.
La interfaz ObjectOutput
se usa al implementar la clase ObjectOutputStream
. El ObjectOutputStream
se construye para serializar el objeto.
Deserializar un objeto en java
La operación opuesta de la serialización se denomina deserialización, es decir, extraer los datos de una serie de bytes se conoce como deserialización, que también se denomina inflado o no severo.
ObjectInputStream
extiende java.io.InputStream
e implementa la interfaz ObjectInput
. Deserializa objetos, matrices y otros valores de un flujo 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 clase ObjectInputStream
para deserializar ese archivo que había sido serializado por la clase ObjectInputStream
. El código anterior crea la instancia utilizando la instancia de la clase FileInputStream
que contiene el objeto de archivo especificado que debe deserializarse porque el constructor ObjectInputStream()
necesita la secuencia de entrada.
La serialización es la conversión de un objeto a una serie de bytes, de modo que el objeto puede guardarse fácilmente en un almacenamiento persistente o transmitirse a través de un enlace de comunicación. El flujo de bytes se puede deserializar y convertir en una réplica del objeto original.
Me atrevo a responder una pregunta de 6 años, agregando un nivel muy alto de comprensión para las personas nuevas en Java
¿Qué es la serialización?
Convertir un objeto en bytes y bytes de nuevo en 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:
ATM: cuando el titular de la cuenta intenta retirar dinero del servidor a través de ATM, la información del titular de la cuenta, como los detalles del retiro, se serializará y se enviará al servidor, donde se deserializan los detalles y se utilizan para realizar operaciones.
Cómo se realiza la serialización en java.
Implementar la interfaz
java.io.Serializable
(interfaz de marcador, por lo que no hay método para implementar).Persista el objeto: use la clase
java.io.ObjectOutputStream
, un flujo de filtro que se envuelve alrededor de un flujo de bytes de nivel inferior (para escribir Objeto en sistemas de archivos o transferir un objeto aplanado a través de un cable de red y reconstruir 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 o los métodos de clase del objeto.
Cuando serializa un objeto de 2 bytes, ve un archivo serializado de 51 bytes.
Pasos de cómo el objeto se serializa y des-serializa.
Responde a: ¿Cómo se convirtió a 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 recursivamente 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 al contenido real.
Si está interesado en obtener más información sobre la serialización de Java, consulte este link .
Edición : Un buen link para leer.
Esto responderá algunas preguntas frecuentes:
Cómo no serializar ningún campo en clase.
Respuesta: usar palabra clave transitoriaCuando la clase secundaria se serializa, ¿la clase principal se serializa?
Respuesta: No, si el padre no está extendiendo el campo de padres de la interfaz serializable no se serializa.Cuando se serializa el padre, ¿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. Reemplace el método writeObject y readObject y lanceNotSerializableException
.segundo. También puedes marcar todos los campos transitorios en clase infantil.
- Algunas clases de nivel de sistema, como Thread, OutputStream y sus subclases, y Socket no son serializables.
Me gustó la forma en que presenta @OscarRyz. Aunque aquí continúo la historia de la serialización que fue escrita originalmente por @amitgupta.
A pesar de que conocía la estructura de la clase de robots y de haber serializado los datos, el científico de Earth 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 Mars estaban esperando el pago completo. Una vez que se realizó 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 robots y todo quedó bien.
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 desde el archivo y restaurarlo se llama deserialización.
¿Cuál es la necesidad de la serialización?
En la arquitectura moderna, siempre hay una necesidad de almacenar el estado del objeto y luego recuperarlo. Por ejemplo, en Hibernate, para almacenar un objeto deberíamos hacer que la clase sea 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 del estado y recuperar la clase. El estado del objeto puede provenir de una base de datos o un jvm diferente o de un componente separado. Con la ayuda de la serialización podemos recuperar el estado del objeto.
Ejemplo de código 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 a la variable Long. El compilador calcula este número según el estado de la clase y los atributos de la clase. Este es el número que ayudará al jvm a identificar el estado de un objeto cuando lee el estado del objeto desde el archivo.
Para eso podemos echar un vistazo a la documentación oficial de Oracle:
El tiempo de ejecución de serialización asocia con cada clase serializable un número de versión, llamado serialVersionUID, que se usa durante la deserialización para verificar que el remitente y el receptor de un objeto serializado hayan cargado clases para ese objeto que sean 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 excepción InvalidClassException. Una clase serializable puede declarar su propio serialVersionUID declarando explícitamente un campo llamado "serialVersionUID" que debe ser estático, final y de tipo long: ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; Si una clase serializable no declara explícitamente un serialVersionUID, entonces el tiempo de ejecución de serialización calculará un valor serialVersionUID predeterminado para esa clase basándose en 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 de serialVersionUID, ya que el cálculo predeterminado de serialVersionUID es altamente sensible a los detalles de la clase que pueden variar dependiendo de las implementaciones del compilador y, por lo tanto, puede dar lugar a inesperadas excepciones de clase Invalid durante la deserialización. Por lo tanto, para garantizar un valor serialVersionUID consistente en diferentes implementaciones del compilador java, una clase serializable debe declarar un valor serialVersionUID explícito. También se recomienda encarecidamente que las declaraciones explícitas de serialVersionUID utilicen el modificador privado siempre que sea posible, ya que dichas declaraciones se aplican solo a los campos de clase de declaración inmediata: serialVersionUID no son útiles como miembros heredados.
Si ha notado que hay otra palabra clave que hemos utilizado 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 veamos 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 utilizamos 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 se lee desde el objeto del archivo. Utiliza readObject para leer los datos del objeto del archivo.
La salida 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]
Observe que itemCostPrice del objeto deserializado es nulo ya que no se escribió.
Ya hemos discutido los conceptos básicos de la serialización de Java en la parte I de este artículo.
Ahora vamos a discutirlo en profundidad y cómo funciona.
Primero vamos a empezar con el serialversionuid.
El serialVersionUID se usa como un control de versión en una clase Serializable.
Si no declara explícitamente un serialVersionUID, JVM lo hará por usted automáticamente, basándose en varias propiedades de la clase Serializable.
Algoritmo de Java de Cálculo de 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 ordenada por nombre.
- Para cada campo de la clase ordenado por nombre de campo (excepto los campos transitorios estáticos privados y 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 escritos 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 escritos como un entero de 32 bits. El descriptor del método.
- El algoritmo SHA-1 se ejecuta en el flujo de bytes producido por DataOutputStream y produce cinco valores de 32 bits sha [0..4]. El valor de hash se ensambla a partir de los valores de 32 bits primero y segundo 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 de 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 recursivamente la descripción de la superclase hasta que encuentra 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 recursivamente los datos asociados con la instancia, comenzando desde la superclase menor hasta la clase más derivada.
Cosas a tener en cuenta:
Los campos estáticos en una clase no pueden ser serializados.
public class A implements Serializable{ String s; static String staticString = "I won''t be serializable"; }
Si el serialversionuid es diferente en la clase de lectura, lanzará una excepción
InvalidClassException
.Si una clase implementa serializable, entonces 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
}
Puede pensar en la serialización como el proceso de convertir una instancia de objeto en una secuencia de bytes (que puede ser binario 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 necesita implementar la interfaz Serializable para que un objeto se pueda serializar.
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 características 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 la clase. Así los métodos no son 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 qué 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 relevante adicional en la serialización de Java: el serialversionUID pero supongo que esto ya es demasiado largo para cubrirlo.
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 van a guardar. Si desea resucitar el objeto nuevamente, debe tener el archivo de clase, ya que 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 Searializable 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 ser serializable.
| * | Serialización de una clase: Convertir un objeto en bytes y bytes de nuevo en objeto (Deserialización).
class NamCls implements Serializable
{
int NumVar;
String NamVar;
}
| => Object-Serialization es el proceso de convertir el estado de un objeto en vapor de bytes.
- | -> Implementar cuando desee que el objeto exista más allá de la vida útil de la JVM.
- | -> Objeto serilizado puede ser almacenado en la base de datos.
- | -> Los objetos serializables no pueden ser leídos ni comprendidos por los seres humanos, por lo que podemos lograr seguridad.
| => Deserialización de objetos es el proceso de obtener el estado de un objeto y almacenarlo en un objeto (java.lang.Object).
- | -> Antes de almacenar su estado, verifica el tiempo serialVersionUID desde el archivo de entrada / red y el archivo .class serialVersionUID son los mismos.
& nbsp & nbspSi no se lanza java.io.InvalidClassException.
| => Un objeto Java solo es serializable, si su clase o cualquiera de sus superclases
- implementa la interfaz java.io.Serializable o
- Su subinterfaz, java.io.Externalizable.
| => Los campos estáticos en una clase no pueden ser serializados.
class NamCls implements Serializable
{
int NumVar;
static String NamVar = "I won''t be serializable";;
}
| => Si no desea serializar una variable de una clase use una 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.
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 (a across a network
), luego, utilizando la deserialización podemos restaurar el gráfico de objetos. Los gráficos de objetos se restauran correctamente utilizando un mecanismo de compartición de referencias. Pero antes de almacenar, compruebe si serialVersionUID de input-file / network y .class file serialVersionUID son los mismos. Si no, lanza una java.io.InvalidClassException
.
Cada clase versionada debe identificar la versión original de la clase para la cual es capaz de escribir secuencias y desde la cual 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 que el desarrollador lo agregue 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
y, por lo tanto, puede dar lugar a conflictos de serialVersionUID inesperados durante la deserialización, lo que hace que falle la deserialización.
Inspeccionando 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 debe agregarse como comportamiento serializable. Aquí Java Virtual Machine (JVM) es responsable de su serialización automática.
Palabra clave transitoria:
java.io.Serializable interface
Al serializar 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.
- Los campos declarados como transitorios o estáticos son ignorados por el proceso de serialización.
TRANSIENT Y VOLATILE
+--------------+--------+-------------------------------------+ | 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 el control completo sobre los contenidos 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 son implementados por 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 versionado 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
written to
/read from
secuencias. La clase de cada objeto serializable se codifica, incluido 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 sobre red
Distribuir el estado del objeto en 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 compartiendo datos e invocando 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
- Implementando Serializable vs Externalizable
Java proporciona un mecanismo, denominado serialización de objetos, en el que un objeto se puede representar como una secuencia de bytes que incluye los datos del objeto, así como información sobre el tipo del objeto y los tipos de datos almacenados en el objeto. Se utiliza principalmente para viajar el estado de un objeto en la red (conocido como cálculo de referencias).