long intellij implement generate calculate java serialization serialversionuid

java - intellij - serialversionuid generator



explícito serialVersionUID considerado dañino? (6)

En mi trabajo, prohibimos explícitamente la especificación de serialVersionUID, exactamente debido a los problemas que plantea.

Además, las clases que persistimos solo se usan para almacenar datos sin lógica interna, por lo que la única forma en que cambian es debido al cambio de miembros de datos.

Probablemente estoy arriesgando algunos votos negativos sobre esto.

Me parece que especificar explícitamente serialVersionUID para nuevas clases es malo. Considere los dos casos de no cambiarlo cuando el diseño debe haber sido cambiado y cambiarlo cuando no debería haberlo hecho.

No cambiar cuando debería haber sido modificado ocurre casi solo cuando es explícito. En este caso, resulta en algunos errores muy sutiles y difíciles de encontrar. Especialmente durante el desarrollo, cuando el diseño de clase cambia a menudo. Pero si no se ha especificado explícitamente, cambiará y la deserialización se romperá fuerte, lo más probable es que se solucione purgando el repositorio.

Cambiarlo cuando debería no debería ocurrir casi solo cuando está implícito. Este es el raro caso en que el diseño de clases ha cambiado, pero aún queremos deserializar de las antiguas manchas serializadas. Es probable que esto quede atrapado durante el control de calidad ( errores extraños después de la actualización de 5.2 a 5.2.1, consulte el seguimiento de la pila adjunta ) y se puede solucionar trivialmente configurando un valor explícito.

¿Comentarios?


Si solo está utilizando la serialización para una llamada a un método remoto, por ejemplo, llamar a un EJB, donde las clases de cliente y servidor y jvm son las mismas, sospecho que es con mucho el uso más común, y luego establecer serialVersionUID explícitamente (como por ejemplo eclipse sugiere) es probable que le provoque un dolor significativo en forma de errores ocasionales e inexplicables, donde las instancias de clases incompatibles se tratan como compatibles debido a la serialVersionUID fija. Las llamadas remotas saldrán mal en forma silenciosa durante la serialización de bajo nivel y el problema solo surgirá más tarde cuando el estado de su objeto sea inconsistente. Encuentra el origen del problema solo cuando se da cuenta de que las clases de cliente y servidor son de alguna manera diferentes (aunque serialVersionUID por supuesto que no). En mi experiencia, configurar serialVersionUID por este motivo hace más daño que bien.

Si, por otro lado, establece explícitamente serialVersionUID para leer en datos antiguos, está leyendo por definición en una versión incompatible y es probable que termine con un objeto en un estado inconsistente o incompleto. En este caso, establecer serialVersionUID es una solución para un problema diferente.


Ya sea que vaya a serialVersionUID o no (sugiero que lo haga), entonces realmente debería considerar la creación de un conjunto completo de pruebas para la compatibilidad en serie.

También vale la pena diseñar el formato de serie con cuidado. Es efectivamente una API pública.


para enfatizar aún más lo que dijo John skeet y para contradecir el comentario:

"Si no lo necesita (es decir, siempre serializa y deserializa con la misma versión de clase), puede omitir la declaración explícita"

Incluso si no está serializando a largo plazo y está usando la misma versión de clase, aún podría tener problemas . si está escribiendo un código cliente-servidor y el código del cliente podría ejecutarse con una versión / implementación de jvm diferente a la del servidor, puede tener los mismos problemas con los valores seriales incompatibles.

para resumir, la única vez que es "seguro" no especificar inviertedas en serie es cuando no está serializando a largo plazo y se le garantiza que todos los consumidores de los datos serializados usarán la misma implementación y versión de jvm que el productor original.

en resumen, no usar serialversionuid es generalmente la situación más dañina.


Cambiar cuando no debería ocurrir por razones distintas a los cambios en el diseño de clases: el problema es que depende de la implementación del compilador. Si depura con Eclipse pero realiza compilaciones de producción con javac, puede terminar con dos conjuntos de datos incompatibles.


Cuando necesite soportar la persistencia a largo plazo a través de la serialización, casi siempre necesitará usar código personalizado para soportar esto y necesitará establecer explícitamente el serialVersionUID , ya que de lo contrario la versión serializada más vieja no podrá ser serialVersionUID por el código más nuevo.

Esos escenarios ya requieren una gran atención para corregir todos los casos, cuando la clase cambia, por lo que el serialVersionUID es el menor de sus problemas.

Si no lo necesita (es decir, siempre serializa y deserializa con la misma versión de clase), puede omitir de forma segura la declaración explícita, ya que el valor calculado se asegurará de que se use la versión correcta.