Pregunta

Cuando la clase implementa Serializable en Eclipse, tengo dos opciones: añadir serialVersionUID(1L) por defecto o serialVersionUID(3567653491060394677L) generado. Creo que primero es más fresco, pero muchas veces vi a la gente que usa la segunda opción. ¿Hay alguna razón para generar long serialVersionUID?

¿Fue útil?

Solución

Por lo que yo puedo decir, eso sería sólo por compatibilidad con versiones anteriores. Esto sólo sería útil si se olvidó de utilizar un serialVersionUID antes, y luego hizo un cambio que usted sabe debe ser compatibles, sino que hace que la serialización de romper.

Vea la Java La serialización de especificaciones para más detalles.

Otros consejos

El propósito de la versión de serialización UID es mantener un seguimiento de las diferentes versiones de una clase con el fin de realizar la serialización válida de objetos.

La idea es generar un identificador que es único para una determinada versión de una clase, que se cambia entonces cuando hay nuevos detalles añadidos a la clase, tales como un nuevo campo, lo que afectaría a la estructura del objeto serializado .

Siempre utilizando el mismo ID, tales como medios 1L que en el futuro, si se cambia la definición de la clase que causa cambios en la estructura del objeto serializado, habrá una buena posibilidad de que los problemas al intentar deserializar un objeto.

Si se omite el ID, Java calcular realmente el ID para usted, basado en campos del objeto, pero creo que es un proceso costoso, por lo que proporciona una manualmente mejorará el rendimiento.

Aquí hay un par de enlaces a artículos que tratan sobre la serialización y control de versiones de las clases:

La razón principal para la generaron una sería para que sea compatible con una versión existente de la clase que ya ha persistido copias.

El valor predeterminado "largo" de la serialVersionUID es el valor predeterminado definido por la Java serialización Especificación , calculado a partir del comportamiento de serialización predeterminada.

Así que si se agrega el número de versión predeterminada, su clase (des) serializar más rápido, siempre y cuando nada ha cambiado estructuralmente, pero que tendrá que tener cuidado de que si cambia la clase (añadir / quitar campos) se también actualizar el número de serie.

Si usted no tiene que ser compatible con flujos de bits existentes, puede simplemente poner 1L allí e incrementar la versión según sea necesario cuando algo cambia. Es decir, cuando la versión de serialización por defecto de la clase cambiada sería diferente de la versión predeterminada de la clase de edad.

A pesar de todo debe crear un serialVersionUID cada vez que defina una clase que implementa java.io.Serializable. Si no lo hace, lo hará se creará de forma automática, pero esto es malo. La auto-generados serialVersionUID se basa en las firmas de los métodos de su clase, por lo si cambia de clase en el futuro para añadir un método (por ejemplo), deserializar los "viejos" versiones de la clase fallará. Esto es lo que puede suceder:

  1. Crea la primera versión de su clase, sin definir el serialVersionUID.
  2. Serialice una instancia de la clase a un almacén persistente; una serialVersionUID se genera automáticamente para usted.
  3. Modificar su clase para agregar un nuevo método, y volver a implementar la aplicación.
  4. Intento de deserializar la instancia que fue serializado en el paso 2, pero ahora se produce un error (cuando debería tener éxito), ya que tiene una diferente auto-generado serialVersionUID.

Si no se especifica un serialVersionUID luego de Java hace a uno sobre la marcha. El serialVersionUID generado es ese número. Si cambia algo en su clase que en realidad no hacer su clase incompatible con verisons por entregas anteriores, pero cambia el hash, entonces es necesario utilizar la generada a muy gran número serialVersionUID (o el número "esperado" de la mensaje de error) . De lo contrario, si desea mantener un registro de todo usted mismo, 0, 1, 2 ... es mejor.

Cuando se utiliza serialVersionUID (1 l) en lugar de generar serialVersionUID (3567653491060394677L) que está diciendo algo.

Usted está diciendo que son 100% seguros de que no existe un sistema que cada vez va a tocar esta clase que tiene una versión serializada incompatible de esta clase con un número de versión 1.

Si usted puede pensar en alguna excusa para su versión historia serializada ser desconocido, que podría ser difícil decir con confianza. En ella está la vida, una clase de éxito será mantenido por muchas personas, viven en muchos proyectos, y residir en muchos sistemas.

Puede agonizan por eso. O se puede jugar a la lotería con la esperanza de perder. Si genera la versión que tiene una pequeña posibilidad de cosas que van mal. Si se asume "Hey, yo apuesto a que nadie ha usado 1 sin embargo," sus probabilidades son más grandes que pequeñas. Es precisamente debido a que todos pensamos 0 y 1 son frescas que tiene mayores probabilidades de golpear a ellos.

-

Cuando se genera serialVersionUID (3567653491060394677L) en lugar de utilizar serialVersionUID (1L) que está diciendo algo.

la gente

Usted está diciendo que pueden ostentar creó manualmente o generadas otros números de versión sobre la historia de esta clase y no le importa porque Longs están volviendo loco grandes números.

De cualquier manera a menos que conozca perfectamente la historia de los números de versión se utiliza cuando la serialización de la clase en todo el universo de donde tiene o va a existir alguna vez, usted está tomando una oportunidad. Si usted tiene el tiempo para hacer 100% seguro 1 es AOK, ir a por ello. Si eso es a mucho trabajo, seguir adelante y ciegamente generar el número. Es más probable que gane la lotería que tener que ir mal. Si es así, hágamelo saber y te voy a comprar una cerveza.

Con toda esta charla de jugar a la lotería que le haya dado la impresión de que se genera aleatoriamente serialVersionUID. De hecho, siempre y cuando el rango de números se distribuye uniformemente sobre cada posible valor de un largo que estaría bien. Sin embargo, en realidad está hecho de esta manera:

http://docs.oracle. com / JavaSE / 6 / docs / plataforma / serialización / spec / class.html # 4100

La única diferencia se obtiene con esto es que no necesita una fuente de azar. Usted está utilizando los cambios de clase en sí para cambiar el resultado. Pero de acuerdo con el principio del palomar todavía hay una posibilidad de que podría ir mal y tienen una colisión. Es increíblemente improbable. Así que buena suerte conseguir una cerveza de mí.

Sin embargo, incluso si la clase referida solamente vivir en un sistema y una base de código, pensando que incrementar el número a mano le da ninguna posibilidad de colisiones sólo significa que usted no entiende los seres humanos. :)

Bueno, serialVersionUID es una excepción a la regla de que “los campos estáticos no reciben serializado”. ObjectOutputStream escribe cada vez que el valor de serialVersionUID la secuencia de salida. ObjectInputStream lee de nuevo y si el valor leído de la corriente no está de acuerdo con el valor serialVersionUID en la versión actual de la clase, entonces se lanza el InvalidClassException. Por otra parte, si no hay serialVersionUID declarado oficialmente en la clase para serializar, compilador agrega automáticamente con un valor generado en base a los campos declarados en la clase.

Debido a que en muchos casos Identificación del defecto no es única. así que creamos para hacer Identificación del concepto único.

Para añadir a la respuesta @ David Schmitt, como regla general yo siempre utilizar el valor predeterminado 1L de convención. Sólo he tenido que volver atrás y cambiar algunos de ellos un par de veces, pero sabía que cuando hice el cambio y actualizado el número predeterminado en uno cada vez.

En mi empresa actual requieren que el número generado automáticamente por eso uso que por convención, pero yo prefiero el defecto. Mi opinión es, si no es una convención en la que trabaja, utilice el valor por defecto, a menos que usted cree que va a estar cambiando constantemente la estructura de clases le serializados por alguna razón.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top