Comprensión profunda de la interfaz serializable

Impresión inicial de Serializalbe

Serializalbe utilizado con frecuencia el objeto de entidad J AVA cuando "implementa Serializable", es generalmente conocido por implementar esta interfaz serializada. Entonces, ¿cuál es el propósito de la serialización?

Ver el código fuente de la interfaz Serializalbe

java.ioSerializable {
}

Es una interfaz vacía, que puede verse como una interfaz icónica. La anotación indica que la clase que no implementa esta interfaz no realizará ninguna serialización o deserialización de su estado. JVM usa este identificador para identificar si se requiere serialización.

Descripción general de la interfaz serializable

Serializable es una interfaz de nivel semántico definida en el paquete java.io y utilizada para implementar la operación de serialización de clases Java. La interfaz de serialización serializable no tiene métodos ni campos, pero se utiliza para identificar la semántica de la serialización. Una clase que implementa la interfaz serializable se puede convertir en un flujo de bytes mediante ObjectOutputStream, y también se puede analizar en un objeto a través de ObjectInputStream. Por ejemplo, podemos escribir un objeto serializado en un archivo, leerlo del archivo nuevamente y deserializarlo en un objeto, es decir, podemos usar la información de tipo y los bytes que representan el objeto y sus datos para recrear el objeto en la memoria.

Y esto es muy importante para los lenguajes de programación orientados a objetos, porque no importa qué lenguaje de programación, la parte subyacente de la operación de E / S todavía la realiza el sistema operativo, y las operaciones de E / S subyacentes son todos flujos de bytes. el tipo de datos del lenguaje de programación en un flujo de bytes, y la operación de lectura implica convertir el flujo de bytes en un tipo de datos específico del tipo de lenguaje de programación. Java es un lenguaje de programación orientado a objetos, y los objetos son los portadores de tipos de sus datos principales. Para completar las operaciones de lectura y escritura de datos de objetos, se necesita una forma de que la JVM sepa cómo convertir los datos de objetos en IO Byte stream, y cómo convertir los datos del flujo de bytes en un objeto específico, y la interfaz serializable asume tal función.

Un experimento, enséñame el código

【Experimento uno】

Podemos usar ejemplos para almacenar el objeto serializado en un archivo y luego deserializarlo del archivo a un objeto. El ejemplo de código es el siguiente:

Primero defina un usuario de objeto serializado:

Serializable por el usuario { 
    Integer String (Integer idString name) { 
        . = Id. = Name }

Primera prueba para escribir el objeto en un archivo (esto usa SpringBoot para establecer una interfaz accesible y ejecuta la operación de escritura del archivo al acceder a esta interfaz):

HelloWorldController { 
    (= = RequestMethod.) 
    Usuario (nombre de cadena) { 
        Usuario usuario = Usuario (nombre) { 
            ObjectOutputStream objectOutputStream = ObjectOutputStream (FileOutputStream ()) objectOutputStream.writeObject (usuario) objectOutputStream.close ()} {eOutputStream.close ()} (eOException 
            . printStackTrace ()} 


        usuario} 
}

Después de acceder a esta interfaz (mi dirección local): http://127.0.0.1:8080/hello/say  , escribimos el objeto Usuario y los datos que lleva en el texto test.txt:

image.png

Verifique que los datos del objeto se conserven en el archivo de disco.

[Experimento 2]

Eliminar la interfaz serializable en la clase de entidad

Usuario { 
    Integer String (Integer idString name) { 
        . = Id. = Name }

Ejecute la interfaz nuevamente, y el error es el siguiente:

image.pngSe lanza una excepción NotSerializableException, lo que genera una excepción no serializable, lo que significa que un objeto que no implementa la interfaz serializable no puede persistir a través de operaciones de E / S, porque la JVM no convierte automáticamente el objeto en un flujo de bytes, por lo que no se realiza ninguna operación. hecho en el programa El objeto de usuario no se puede almacenar directamente en la capa de persistencia.

【Experimento tres】

Convierta los datos del objeto previamente persistentes al archivo test.txt en objetos Java nuevamente, el código es el siguiente:


Acerca de la serialización y deserialización

Serialización: El proceso de convertir un objeto Java en una secuencia de bytes. Es el proceso de convertir estos objetos en la memoria en una serie de bytes (bytes) de descripción.

Deserialización: El proceso de convertir un flujo de bytes en un objeto Java.

escenas que se utilizarán

1, la memoria necesaria para guardar el estado de los datos de la imagen en un archivo o base de datos, cuando se prepara, por ejemplo, cuando usamos mybatis persistence layer frame insertar datos de objeto en la base de datos

2. Cuando la comunicación de red necesita usar sockets para transferir objetos en la red, como cuando usamos el protocolo RPC para la comunicación de red.


Suplemento (tomado de otros sitios web)

Acerca de serialVersionUID

Para la JVM, la clase que se persistirá debe tener una marca. Solo con esta marca la JVM puede permitir que el objeto creado por la clase se convierta en datos de bytes a través de su sistema IO para lograr la persistencia, y esta marca es interfaz serializable. En el proceso de deserialización, debe usar serialVersionUID para determinar qué clase cargar el objeto, por lo que cuando implementamos la interfaz serializable, generalmente tenemos que definir serialVersionUID de la manera más explícita posible, como por ejemplo:

private static final long serialVersionUID = 1L;

在反序列化的过程中,如果接收方为对象加载了一个类,如果该对象的serialVersionUID与对应持久化时的类不同,那么反序列化的过程中将会导致InvalidClassException异常。例如,在之前反序列化的例子中,我们故意将User类的serialVersionUID改为2L,如:

private static final long serialVersionUID = 2L;

那么此时,在反序例化时就会导致异常,如下:

java.io.InvalidClassException: cn.wudimanong.serializable.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2     at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)     at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1880)     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1746)     at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2037)     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1568)     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:428)     at cn.wudimanong.serializable.SerializableTest.readObj(SerializableTest.java:31)     at cn.wudimanong.serializable.SerializableTest.main(SerializableTest.java:44)

Si no declaramos explícitamente el serialVersionUID en la serialización, el tiempo de ejecución de la serialización calculará el valor serialVersionUID predeterminado de la clase de acuerdo con todos los aspectos de la clase. Sin embargo, el funcionario de Java recomienda encarecidamente que todas las clases que se serialicen declaren explícitamente el campo serialVersionUID, porque si depende en gran medida de la JVM para generar el serialVersionUID de forma predeterminada, puede hacer que se acople con los detalles de implementación del compilador, lo que puede conducir a la deserialización. Se produjo una InvalidClassException inesperada durante el proceso. Por lo tanto, para asegurar la consistencia de los valores serialVersionUID implementados en diferentes compiladores Java, aquellos que implementan la interfaz Serializable deben declarar explícitamente el campo serialVersionUID.

Además, la declaración del campo serialVersionUID debe modificarse tanto como sea posible con la palabra clave private. Esto se debe a que la declaración de este campo solo se aplica a la clase declarada. Es inútil que este campo sea heredado por subclases como miembro. variable! Hay un lugar especial que debe tenerse en cuenta., La clase de matriz no puede declarar explícitamente el serialVersionUID, porque siempre tienen el valor calculado predeterminado, pero el requisito de hacer coincidir el valor de serialVersionUID también se abandona durante la deserialización de la clase de matriz .



Supongo que te gusta

Origin blog.51cto.com/13238147/2667199
Recomendado
Clasificación