Recientemente, he compilado el conocimiento básico de Java, y la información sobre la serialización y la deserialización de Java se ha resuelto en detalle. Tomaré una nota aquí, con la esperanza de que también ayude a amigos que lean este artículo.
1. El concepto de serialización y deserialización
El proceso de convertir un objeto en una secuencia de bytes se llama serialización de un objeto.
El proceso de restauración de una secuencia de bytes en un objeto se llama deserialización de un objeto.
Hay dos usos principales para la serialización de objetos:
1) Guarde la secuencia de bytes de objetos permanentemente en el disco duro, generalmente en un archivo;
2) Transfiera la secuencia de bytes de objetos en la red.
En muchas aplicaciones, ciertos objetos deben ser serializados, de modo que salgan del espacio de memoria y pasen al disco duro físico para el almacenamiento a largo plazo. Por ejemplo, el más común es el objeto de sesión en el servidor web. Cuando 100,000 usuarios acceden simultáneamente, pueden aparecer 100,000 objetos de sesión, y la memoria puede no poder soportarla. Por lo tanto, el contenedor web serializará primero algunas versiones al disco duro y esperará hasta que se use, y luego restaurar los objetos guardados en el disco duro a la memoria.
Cuando dos procesos se comunican de forma remota, pueden enviarse varios tipos de datos entre sí. No importa qué tipo de datos sean, se transmitirá en la red en forma de secuencia binaria. El remitente debe convertir este objeto Java en una secuencia de bytes para transmitirse en la red; El receptor necesita restaurar los bytes en un objeto Java.
2. API de serialización en la biblioteca de clases JDK
java.io.objectOutputStream representa la secuencia de salida del objeto. Su método WriteObject (object obj) puede serializar el objeto OBJ especificado por el parámetro y escribir la secuencia de byte obtenida en una secuencia de salida de destino.
java.io.objectInputStream representa la secuencia de entrada del objeto. Su método ReadObject () lee secuencias de byte de una secuencia de entrada de origen, las deserializa en un objeto y las devuelve.
Solo se pueden serializar los objetos de clases que implementan interfaces serializables y externalizables. La interfaz externalizable hereda de la interfaz serializable. Las clases que implementan la interfaz externalizable controlan completamente el comportamiento de serialización, mientras que las clases que solo implementan la interfaz serializable pueden adoptar el método de serialización predeterminado.
La serialización del objeto incluye los siguientes pasos:
1) Cree una secuencia de salida de objeto, que puede envolver otro tipo de transmisión de salida de destino, como la transmisión de salida de archivo;
2) Escriba el objeto a través del método writeObject () de la secuencia de salida del objeto.
Los pasos para deserializar un objeto son los siguientes:
1) Cree una secuencia de entrada de objeto que pueda envolver un tipo diferente de secuencia de entrada de origen, como la secuencia de entrada de archivo;
2) Lea el objeto a través del método ReadObject () del flujo de entrada del objeto.
Ejemplos de serialización de objetos y desequenciación:
Definir una clase de persona para implementar la interfaz Serializable
1 importar java.io.serializable; 2 3 /** 4 * <p> ClassName: Person <p> 5 * <p> Descripción: Prueba de serialización del objeto y deserialización <p> 6 * @author Xudp 7 * @version 1.0 v 8 * @CreateTime 2014-6-9 02:33:25 PM 9 * /10 Persona de clase pública implementa serializable {11 12 /** 13 * Serialización Id14 * /15 Privado STAT SerialVersionUid = -5809782578272943999l; 16 private int Age; 17 Nombre de cadena privada; 18 Private String Sex; 19 20 public int getAge () {21 return Age; 22} 23 24 public String public String getName () {25 Nombre de retorno; 26} 27 28 String public String getSex () {29 Return Sex; 30} 31 32 set de set. edad; 34} 35 36 public void setName (nombre de cadena) {37 this.name = name; 38} 39 40 public void setsex (sexo de cadena) {41 this.sex = sex; 42} 43}Serializar y deserializar objetos de clase de persona
import java.io.file; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.fileOutputStream; import java.io.ioException; import java.io.ObjectInputStream; import java.io.ObjectUxTream; import java.text.messageAformat;/clasess; TestObjSerializeAndDeserialize <p> * <p> Descripción: Serialización y deserialización de objetos de prueba <P> * @Author Xudp * @version 1.0 v * @CreateTime 2014-6-9 03:17:25 PM */clase public TestObjSerializeAnEndDeserialize {public static void Main (String [] excepción) Arg. SerializePerson (); // serializar persona de objeto de la persona p = deserializeSerson (); // Perons deseriales System.out.println (MessageFormat.Format ("name = {0}, edad = {1}, sexo = {2}", p.getName (), p.getage (), p.getSex ())); } / ** * MethodName: SerializePerson * Descripción: Serialize Person Object * @author Xudp * @throws FileNotFoundException * @throws ioException * / private static void serializeperson () lanza FileNotFoundException, ioexception {persona persona = nueva persona (); persona.setName ("gaCl"); persona.setaje (25); persona.setsex ("hombre"); // secuencia de salida del objeto ObjectOutputStream, almacene el objeto de persona en el archivo persona.txt en el disco E y complete la operación de serialización del objeto de persona. ObjectOutputStream oo = new ObjectOutputStream (new FileOutputStream (nuevo archivo ("e: /person.txt"))); oo.writeObject (persona); System.out.println ("¡La serialización del objeto de la persona fue con éxito!"); oo.close (); }/** * MethodName: Deserializeperson * Descripción: Deserializeperson Object * @author Xudp * @return * @throws excepción * @throws ioexception */private static persona deserializeSerson () lanza excepción, ioexception {objectStream OIS = new ObjectSputStam (new FileStream (new File ("e: /person); Persona persona = (persona) ois.readObject (); System.out.println ("¡Deserialización del objeto de persona con éxito!"); persona de regreso; }}Los resultados de la ejecución del código son los siguientes:
Después de serializar a la persona con éxito, se generó un archivo de persona.
3. El papel de SerialversionUid
Seri Al versi ui D: literalmente significa número de versión serializado. Todas las clases que implementan la interfaz serializable tienen una variable estática que representa el identificador de versión serializado.
Private estático final Long SerialVersionUid
Si SerialVersionUid no se agrega a la clase, aparecerá la siguiente advertencia.
Al hacer clic con el mouse, aparecerá un cuadro de diálogo que genera SerialVersionUid, como se muestra en la figura a continuación:
Hay dos formas de generar serialversionuid:
La serie de serialsionuid generado de esta manera es 1L, por ejemplo:
Private static final Long SerialVersionUid = 1L;
La serie de serialsionUid generada de esta manera se genera en función del nombre de clase, el nombre de la interfaz, el método y el atributo, etc., por ejemplo:
Private static final Long SerialVersionUid = 4603642343377807741l;
Después de agregar, la advertencia no aparecerá, como se muestra a continuación:
Después de hablar de ello, ¿cuál es el uso de SerialVersionUid (número de versión serializado)? Usemos el siguiente ejemplo para ilustrar el papel de SerialVersionUid y ver el siguiente código:
1 importar java.io.file; 2 importar java.io.fileInputStream; 3 importar java.io.filenotfoundException; 4 importar java.io.fileOutputStream; 5 importar java.io.ioException; 6 importar java.io.objectInputStream; 7 import java.io.objectOutputStream; 8 importar java.io.serializable; 9 10 public class testSerialVersionUid {11 12 public static void main (string [] args) lanza la excepción {13 serializizeCustomer (); // Serialize Customer Object 14 Cliente Customer = DeserializeMerer (); // Objeto de cliente deserial 15.Println (Cliente); 16} 17 18/** 19 * Método: Método: Método SERIACUSTOMER 20 * SERIALIS * @author xudp22 * @throws filenotFoundException23 * @throws ioexception24 */25 private static void serializizeCustomer () lanza FileNotFoundException, 26 IOException {27 Cliente Customer = nuevo Cliente ("GACL", 25); 28 // ObjectStream OuttutStream OBJETOUTOUTTURT SEAM OO = New Custod FileOutputStream (30 nuevo archivo ("e: /customer.txt"))); 31 oo.writeObject (cliente); 32 System.out.println ("Serialización de objetos del cliente con éxito!"); 33 oo.Close (); 34} 35 36 /** 37 * MethodName: deserializerer 38 * Descripción: deserializeSecustomer 39 * XUDP40 * @return41 * @throws Exception42 * @throws ioException43 */44 privado static static deserializizeCustomer () lanza excepción, ioexception {45 objectInputStream OIS = new ObjectInputStream (nuevo FileInputStream (46 Nuevo archivo ("E: /Customer.txt"))); 47 Customer Customer = (NEW FILEINPUTSTREAM (46 Nuevo archivo ("E: /Customer.txt")); OIS.ReadObject (); 48 System.out.println ("¡La deserialización del objeto del cliente fue exitosa! "); 49 Return Customer; 50} 51} 52 53 /** 54 * <p> ClassName: Customer <p> 55 * <p> Descripción: el cliente implementa la interfaz serializable y puede ser serializada <p> 56 * @author Xudp57 * @version 1.0 v58 * @CreateTime 2014-6-9 04: 20: 1759 pm * /60 SERIATENT {61 // no SerialVersionUid62 Nombre de cadena privada; 63 private int Age; 64 65 Customer público (Nombre de cadena, int Age) {66 this.name = name; 67 this.age = age; 68} 69 70 / * 71 * @methodname toString72 * @Description Rewrite the Tostring () Método de la clase de ojal 733333333 * @methodname String75 * @see java.lang.object#toString () 76 */77 @override78 public string toString () {79 return "name =" + name + ", age =" + edad; 80} 81}Resultados de ejecución:
Tanto la serialización como la deserialización fueron exitosas.
Modificemos la clase del cliente y agregemos un atributo sexual adicional, de la siguiente manera:
1 clase El cliente implementa serializable {2 // No se define SerialVersionUid en el nombre de cadena privada de Clase Clase 3; 4 Private Int Age; 5 6 // Nuevo atributo de sexo 7 sexo de cuerda privada; 8 9 Public Customer (Nombre de cadena, int Age) {10 this.name = name; 11 this.age = age; 12} 13 14 Customer público (nombre de cadena, int Age, String Sex) {15 this.name = name; 16 this.age = edad; 17 this.sex = sex; 18} 19 20 / * 21 * @methodnnnnning22 * @Description Rewrite the tostring () Method de the Wathodnam 23 * xudp24 * @return string25 * @see java.lang.object#toString () 26 */27 @overRide28 public string toString () {29 return "name =" + name + ", age =" + edad; 30} 31}Luego realice la operación de desbloqueo y se lanzará la siguiente información de excepción:
1 excepción en el hilo "principal" java.io.invalidclassexception: cliente; 2 clase local Incompatible: 3 Stream ClassDesC SerialVersionUID = -88175599799432325, 4 clase local SerialVersionUid = -5182532647273106745
Esto significa que la clase en la secuencia de archivos y la clase en la classpath, es decir, la clase modificada, son incompatibles. Están bajo las consideraciones del mecanismo de seguridad. El programa arroja un error y se niega a cargarse. Entonces, ¿qué pasa si realmente tenemos la necesidad de agregar un campo o método después de la serialización? ¿Qué tengo que hacer? Eso es especificar la serie de serialUid. En el ejemplo de TestSerialVersionUid, si no se especifica la VersionUid de la clase del cliente, entonces el compilador Java realizará automáticamente un algoritmo de resumen para esta clase, similar al algoritmo de huellas digitales. Mientras el archivo tenga un espacio más, el UID resultante será completamente diferente, lo que se puede garantizar que este número es único entre muchas clases. Por lo tanto, después de agregar un campo, ya que el SerialVersionUid no se especifica, el compilador genera un UID para nosotros, que por supuesto no es el mismo que el guardado en el archivo antes, por lo que hay dos errores con números de versión de serialización inconsistentes. Por lo tanto, siempre que especifiquemos SerialVersionUiduid nosotros mismos, podemos agregar un campo o método después de la serialización sin afectar la restauración posterior. El objeto restaurado aún se puede usar, y también hay más métodos o atributos para usar.
A continuación, continúe modificando la clase del cliente y especifique una serie de serialUid para el cliente. El código modificado es el siguiente:
Clase Cliente Implementa Serializable { / ** * SerialVersionUid (número de versión serializado) definido en la clase del cliente * / Private static final Long SerialVersionUid = -5182532647273106745l; nombre de cadena privada; edad privada int; // Atributo de sexo nuevo // sexo de cadena privada; CLIENTE PUBLICO (Nombre de cadena, int Age) {this.name = name; this.age = edad; } /*Public Customer (nombre de cadena, int Age, String Sex) {this.name = name; this.age = edad; this.sex = sexo; } *// * * @Methodname toString * @Description Reescribe el método toString () de la clase de objeto * @author xudp * @return string * @see java.lang.Object#toString () */ @Override public string toString () {return "name =" + name + ", edad =" + edad; }}Vuelva a ejecutar la operación de serialización, esirialice el objeto del cliente al almacenamiento de archivos Customer.txt en el disco duro local, luego modifique la clase del cliente y agregue el atributo sexual. El código de clase de cliente modificado es el siguiente:
Clase Cliente Implementa Serializable { / ** * SerialVersionUid (número de versión serializado) definido en la clase del cliente * / Private static final Long SerialVersionUid = -5182532647273106745l; nombre de cadena privada; edad privada int; // Nuevo atributo de sexo sexo de cadena privada; CLIENTE PUBLICO (Nombre de cadena, int Age) {this.name = name; this.age = edad; } public Customer (Nombre de cadena, int Age, String Sex) {this.name = name; this.age = edad; this.sex = sexo; } / * * * @Methodname toString * @Description Reescribe el método toString () de la clase de objeto * @author xudp * @return string * @see java.lang.object#toString () * / @override public string toString () {return "name =" + name + ", edad =" + edad; }}Realice la operación de desbloqueo, y la delequencia tendrá éxito esta vez, como se muestra a continuación:
4. El valor de SerialVersionUid
El valor del entorno de tiempo de ejecución de Java genera automáticamente el valor de VialversionUid en función de los detalles internos de la clase. Si el código fuente de la clase se modifica y recompina, el valor de la serie SerialSionUid del archivo de clase recién generado también puede cambiar.
El valor predeterminado del SerialVersionUid de una clase depende completamente de la implementación del compilador Java. Para la misma clase, la compilación con diferentes compiladores de Java puede conducir a diferentesversionUids, y también puede ser el mismo. Para mejorar la independencia y la certeza de SerialVersionUid, se recomienda definir la vida en serie que se muestra en una clase en serie, asignándolo un valor claro.
Hay dos propósitos para definir explícitamente SerialVersionUid:
1. En algunos casos, se espera que diferentes versiones de la clase sean compatibles con la serialización, por lo que es necesario garantizar que diferentes versiones de la clase tengan la misma serie en serie;
2. En algunos casos, no se espera que diferentes versiones de la clase sean compatibles con la serialización, por lo que es necesario garantizar que diferentes versiones de la clase tengan diferentes VersionUids.
Gracias por leer, espero que pueda ayudarte. ¡Gracias por su apoyo para este sitio!