2010-08-25 18 views

Respuesta

22

serialVersionUID no se genera de forma automática, ya que es peligroso. Cuando se establece serialversionuid, implica que dos versiones de una clase son compatibles con respecto a la serialización.

Imagine que tiene una clase llamada Foo, y tiene no serialversionuid (valor predeterminado), y serializa una instancia de Foo en un archivo. Más tarde, agregas algunos miembros nuevos a la clase Foo. Si intenta deserializar el objeto Foo del archivo, obtendrá un error de serialización que indica que los objetos son incompatibles. Ellos son incompatibles, esto es lo que quiere y es el predeterminado. Son incompatibles porque los nuevos miembros de la clase Foo no se pueden inicializar a partir de la antigua instancia serializada de Foo.

Ahora, podría decir: "No me importa, en mi aplicación es aceptable que esos campos no se inicialicen". Si ese es el caso realmente es el caso, puede configurar el serialversionuid de la nueva clase Foo para que sea la misma que antigua clase Foo. Esto le dirá a Java que los objetos son compatibles con respecto a serializablity, y Java no se quejará cuando deserialice la antigua instancia de Foo en la nueva clase Foo (pero los nuevos campos seguirán sin inicializarse).

Si está creando una nueva clase por primera vez, y se establece la serialVersionUID, que están entrando en un contrato. Ese contrato es, "Para todas las versiones futuras de esta clase con el mismo valor de serie serial, garantizaré que sean compatibles con respecto al estado y la serialización".

Si cambia una clase, y que explícitamente desea no permitir deserialización de las versiones anteriores, puede cambiar el serialVersionUID a un nuevo valor. Esto provocará que se genere una excepción si se intenta deserializar un objeto antiguo en una nueva instancia de clase.

+0

Eso tiene sentido. Eso es algo más en lo que puedo pensar. –

+8

No estoy seguro de por qué esto está marcado como la respuesta correcta ya que serialVersionUID * se * genera automáticamente. Además, dependiendo de la situación, puede haber un valor en los ID generados automáticamente, ya que aseguran un nuevo número cuando se modifica la clase, en lugar de que alguien cambie el código y luego lo olvide. Pero obviamente no para todos los casos, como esta publicación señala correctamente. – nilskp

+0

Esto es tan simple, y sin embargo, pocas personas lo entienden (¿o pueden molestarse en entenderlo?). Supongo que por la cantidad de bloqueo de mayúsculas que usa, también está frustrado por esto. –

9

Se genera automáticamente, según la estructura de la clase. Si la estructura cambia, la identificación se regenera (según el serialization specification es un hashof de la clase).

Así que mejor defina un serialVersionUID explícito.

+6

_Así que será mejor que definas un explícito serialVersionUID._ Tienes razón, pero es mejor que sepan qué hacer para administrar esa variable con respecto a la forma serializada de la clase o es un ejercicio inútil. – McDowell

+0

Buen punto, mucha documentación sobre eso (que necesito leer). –

2

Si utilizas Eclipse como IDE, puede hacer clic derecho sobre la advertencia sobre la falta serialVersionUID y obtendrá dos opciones:

1) Definir el valor predeterminado Eclipse, que tiene el valor de 1 litro ; o
2) Defina un valor largo generado aleatoriamente

Si le importa el control de versiones de objetos serializados, necesitará regenerar manualmente un nuevo valor cada vez que modifique la clase. El Javadoc para la interfaz Serializable tiene esto que decir acerca de lo que sucede si no se declara una serialVersionUID en absoluto:

Si una clase serializable no declara explícitamente un serialVersionUID, entonces el tiempo de ejecución de serialización calculará un valor predeterminado serialVersionUID valor para esa clase basado en varios aspectos de la clase, como se describe en la especificación de serialización de objetos de Java (TM). Sin embargo, se recomienda encarecidamente que todas las clases serializables declaren explícitamente los valores de serialVersionUID, ya que el cómputo serialVersionUID predeterminado es muy sensible a los detalles de clase que pueden variar dependiendo de las implementaciones del compilador, y puede dar como resultado inesperadas InvalidClassExceptions durante la deserialización. Por lo tanto, para garantizar un valor consistente de SerialVersionUID en diferentes implementaciones del compilador Java, una clase serializable debe declarar un valor serialVersionUID explícito.

En la práctica, he encontrado que incluso si se inicia con el código fuente idénticos en dos o más máquinas controladas (fuera de Subversion, por ejemplo), donde serialVersionUID no estaba definido en una clase, el valor generado por el compilador de la clase es diferente en cada máquina cuando se compila el código. Esto puede causar errores confusos durante el desarrollo.

Si está seguro de que nunca tendrá una situación en la que tenga objetos serializados obsoletos que no estén sincronizados con una versión más nueva de la clase (o dos JVM que envíen objetos serializados fuera de sincronización a cada uno otra, tal vez a través de una red o conexión de socket), entonces simplemente establezca un valor de 1L para serialVersionUID y déjelo así para siempre.

http://download-llnw.oracle.com/javase/6/docs/api/java/io/Serializable.html

+1

"Aleatorio" no es lo mismo que "generado". Para el mismo (o similar) archivo de origen, estoy bastante seguro de que la herramienta está garantizada para darle el mismo UUID. –

+1

'Necesitará regenerar manualmente un nuevo valor cada vez que modifique la clase'. Definitivamente no. Esto es exactamente lo opuesto a lo que deberías hacer. – EJP

+0

Y el valor predeterminado no es 1L. – EJP

Cuestiones relacionadas