java - long - Use el serialVersionUID o suprima las advertencias?
serializable in java (12)
Quiero crear una clase que, por ejemplo, amplíe HttpServlet? Mi compilador me advierte que mi clase debería tener un serialVersionUID. Si sé que este objeto nunca se serializará, ¿debería definirlo o agregar una anotación para suprimir esas advertencias?
¿Qué harías y por qué?
¡Me rehúso a que Eclipse me aterrorice para agregar desorden a mi código!
Simplemente configuro Eclipse para que no genere advertencias cuando falta el serialVersionUID.
Deje que Eclipse genere una ID. Rapido y Facil. Las advertencias no deben ignorarse. También le ahorra muchos problemas si alguna vez llega al punto donde el objeto / tiene / debe ser serializado.
Depende.
Si usa compiladores diferentes para compilar su código fuente varias veces, su código compilado podría tener diferentes serializaciónIds que romperán la serialización. Luego, debe apegarse a una serialización constante explícitamente en su código. Debe ser estático y final y por clase (no heredable).
Sin embargo, si siempre compila su código con un compilador específico y siempre despliega su código de una sola vez en todas sus máquinas virtuales, es probable que necesite una verificación estricta de la versión y desea asegurarse de que cada vez que haya una sola versión del código ejecutándose, en ese caso, solo debes suprimir la advertencia. Por lo tanto, en caso de que una VM no se implemente correctamente y ejecute la versión anterior de su código, probablemente espere una excepción durante la serialización en lugar de objetos deserializados. Este es mi caso, solíamos tener un clúster muy grande y necesitamos una verificación estricta de la versión para descubrir cualquier problema de implementación.
De todos modos, probablemente debe evitar la serialización siempre que sea posible, ya que la serialización predeterminada es muy lenta en comparación con los búferes de protocolo o de ahorro y no es compatible con la interoperabilidad entre idiomas.
Es bueno generar SVUID para cada clase implementando serializable. El motivo es simple Nunca se sabe cuándo será serializado por usted o por un tercero. Se pueden configurar muchos servicios que serializarán servlets. Para cada IDE existe un plugin que genera uno o simplemente usa template y establece svuid = 1L.
Esa advertencia me vuelve loco, porque cada vez que subclases una clase Swing, sabes que nunca la serializarás, pero existe esa advertencia estúpida. Pero sí, dejé que Eclipse genere uno.
Gracias @ Steve Jessop por su respuesta sobre esto. Fueron 5 líneas de código ... apenas una molestia.
@SuppressWarnings("serial")
justo encima de la clase en cuestión.
También agregué este método:
private void writeObject(ObjectOutputStream oos) throws IOException {
throw new IOException("This class is NOT serializable.");
}
Espero que eso sea lo que Steve quiso decir :)
Incluso si usted sabe que este objeto será serializado, no hay necesidad de generar serialVersionUID porque Java lo generará automáticamente y automáticamente hará un seguimiento de los cambios para que su serialización siempre funcione bien. Debe generarlo solo si sabe lo que está haciendo (compatibilidad de serialización hacia atrás, seguimiento de cambio manual, etc.)
Entonces, diría que suprimir la advertencia es la mejor y más segura solución en la mayoría de los casos.
No conozco las mejores prácticas de Java, pero se me ocurre que si usted afirma que la serialización nunca ocurrirá, puede agregar un método writeObject que arroje. Luego suprima la advertencia, a salvo sabiendo que posiblemente no se aplique a ti.
De lo contrario, es posible que en el futuro alguien serialice su objeto a través de la clase principal y termine con un formulario serializado predeterminado donde:
- el formulario no es compatible entre las diferentes versiones de tu código.
- has suprimido la advertencia de que este es el caso.
Agregar una ID suena como un bodge, ya que lo que realmente quieres hacer es no serializar. Esperar que las personas que llaman no serialicen su objeto significa que espera que ellos "sepan" cuando su HttpServlet es de su clase. Esa brecha de polimorfismo está en tu cabeza por tener un objeto Serializable que no debe ser serializado, y lo menos que puedes hacer es asegurarte de que las personas incautadas lo sepan.
Por favor, siga este enlace para obtener una explicación detallada: http://technologiquepanorama.wordpress.com/2009/02/13/what-is-use-of-serialversiouid/
Si no planea serializar instancias, agregue un SuppressWarning.
Un ID de serie generado puede ser un poco peligroso. Sugiere que intencionalmente le proporcionó un número de serie y que está listo para serializar y deserializar. Es fácil olvidarse de actualizar el número de serie en una versión más nueva de su aplicación donde se cambia su clase. La deserialización fallará si los campos de clase han sido cambiados. Tener un SuppressWarning al menos le dice al lector de su código que no tenía la intención de serializar esta clase.
Si omite un serialVersionUID java, generará uno para la clase en tiempo de compilación (cambia con cada compilación).
Al deserializar objetos, se compara el serialVersionUID del objeto deserializado con el de la clase en el jvm. Si son diferentes, se los considera incompatibles y se lanza una excepción. Esto puede suceder, por ejemplo, después de actualizar su programa y deserializar clases antiguas.
Siempre uso 1L para serialversionUID. No duele (en comparación con el valor predeterminado generado) y aún deja la opción de romper la compatibilidad más adelante al incrementar la identificación.
Si sabe que sus aplicaciones nunca serializan cosas, suprima la advertencia en toda la aplicación. Esto se puede hacer usando los argumentos de la línea de comando javac:
javac -Xlint -Xlint:-serial *******
De esta forma tendrá todas las advertencias excepto "serial". IDE-s y herramientas de compilación como Maven / SBT / Gradle funcionan bien con eso.