java - usar - tipos de serializacion
¿Por qué Java necesita una interfaz Serializable? (13)
Aparentemente todo era serializable en algunos diseños preliminares, pero debido a cuestiones de seguridad y corrección, el diseño final terminó como todos sabemos.
Fuente: ¿Por qué las clases deben implementar Serializable para ser escritas en ObjectOutputStream? .
Trabajamos mucho con la serialización y tener que especificar la etiqueta Serializable en cada objeto que usamos es una especie de carga. Especialmente cuando se trata de una clase de terceros que realmente no podemos cambiar.
La pregunta es: dado que Serializable es una interfaz vacía y Java proporciona una sólida serialización una vez que se agregan los implements Serializable
, ¿por qué no hicieron que todo fuera serializable y eso es todo?
¿Qué me estoy perdiendo?
Bueno, mi respuesta es que esto es sin una buena razón. Y de sus comentarios puedo ver que ya lo aprendió. Otros idiomas intentan serializar todo lo que no salta en un árbol después de haber contado hasta 10. Un objeto debe ser serializable por defecto.
Entonces, lo que básicamente necesita hacer es leer todas las propiedades de su clase de terceros usted mismo. O bien, si esa es una opción para usted: descompile, coloque la maldita palabra clave allí y vuelva a compilar.
Creo que fue para asegurarse de que usted, como programador, sepa que su objeto puede ser serializado.
Creo que tanto las personas de Java como las de .Net se equivocaron esta vez, hubiera sido mejor hacer todo serializable de forma predeterminada y solo necesitar marcar aquellas clases que no se pueden serializar de forma segura en su lugar.
Por ejemplo, en Smalltalk (un lenguaje creado en los años 70), cada objeto es serializable por defecto. No tengo idea de por qué este no es el caso en Java, considerando el hecho de que la gran mayoría de los objetos son seguros para serializar y solo algunos de ellos no lo son.
Marcar un objeto como serializable (con una interfaz) mágicamente no hace que ese objeto sea serializable, fue serializable todo el tiempo , es solo que ahora expresaste algo que el sistema podría haber encontrado por sí mismo, así que no veo una buena razón para la serialización es como es ahora.
Creo que fue una mala decisión de los diseñadores o que la serialización fue una ocurrencia tardía, o que la plataforma nunca estuvo lista para hacer serialización por defecto en todos los objetos de forma segura y consistente.
Hay algunas cosas en Java que simplemente no se pueden serializar porque son específicas del tiempo de ejecución. Cosas como streams, threads, runtime, etc. e incluso algunas clases de GUI (que están conectadas al sistema operativo subyacente) no se pueden serializar.
La función principal de Serializable en Java es hacer, de forma predeterminada, todos los demás objetos no serializables. La serialización es un mecanismo muy peligroso, especialmente en su implementación predeterminada. Por lo tanto, al igual que la amistad en C ++, está desactivada por defecto, incluso si cuesta un poco hacer las cosas serializables.
La serialización agrega restricciones y problemas potenciales ya que la compatibilidad de la estructura no está asegurada. Está bien que esté apagado por defecto.
Tengo que admitir que he visto muy pocas clases no triviales en las que la serialización estándar hace lo que yo quiero. Especialmente en el caso de estructuras de datos complejas. Por lo tanto, el esfuerzo que haría al hacer que la clase sea serializable, reducirá el costo de agregar la interfaz.
La serialización está plagada de trampas. El soporte de serialización automática de este formulario hace que los elementos internos de clase sean parte de la API pública (razón por la cual javadoc le proporciona las formas persistentes de las clases ).
Para la persistencia a largo plazo, la clase debe ser capaz de decodificar este formulario, lo que restringe los cambios que puede realizar en el diseño de la clase. Esto rompe la encapsulación.
La serialización también puede conducir a problemas de seguridad. Al poder serializar cualquier objeto al que haga referencia, una clase puede acceder a datos que normalmente no podría (mediante el análisis de los datos de bytes resultantes).
Hay otros problemas, como la forma serializada de las clases internas que no están bien definidas.
Hacer que todas las clases sean serializables agravaría estos problemas. Echa un vistazo a Effective Java Second Edition , en particular, el Ítem 74: Implementa Serializable juiciosamente .
Lea esto para comprender la interfaz serializable y por qué deberíamos hacer que solo unas pocas clases sean serializables y también nos complacemos en dónde usar la palabra clave transitoria en caso de que deseemos eliminar algunos campos del procedimiento de almacenamiento.
No todo es genuinamente serializable. Tome una conexión de red, por ejemplo. Puede serializar los datos / estado de su objeto de socket, pero se perderá la esencia de una conexión activa.
Para algunas clases, especialmente aquellas que representan algo más físico como un archivo, un socket, un subproceso o una conexión de base de datos, no tiene ningún sentido serializar las instancias. Para muchos otros, la serialización puede ser problemática porque destruye las restricciones de exclusividad o simplemente te obliga a tratar con instancias de diferentes versiones de una clase, que es posible que no desees.
Podría decirse que podría haber sido mejor hacer que todo fuera serializable por defecto y hacer que las clases no fueran serializables a través de una palabra clave o interfaz de marcador, pero entonces, quienes deberían usar esa opción probablemente no lo pensarían. De la forma en que es, si necesita implementar Serializable, se lo dirá una excepción.
Si bien estoy de acuerdo con los puntos hechos en otras respuestas aquí, el verdadero problema es con la deserialización: si la definición de la clase cambia, existe un riesgo real de que la deserialización no funcione. ¡Nunca modificar los campos existentes es un gran compromiso para el autor de una biblioteca! Mantener la compatibilidad de la API es una tarea ardua como lo es.
Tener que indicar explícitamente que las instancias de una cierta clase son serializables, el lenguaje te obliga a pensar si deberías permitir eso. Para la serialización de objetos de valor simple es trivial, pero en casos más complejos necesita pensar detenidamente.
Con solo confiar en el soporte de serialización estándar de la JVM, se expone a todo tipo de problemas de versiones repugnantes.
Unicidad, referencias a recursos "reales", temporizadores y muchos otros tipos de artefactos NO son candidatos para la serialización.
Una clase que necesita persistir en un archivo u otro medio tiene que implementar una interfaz Serializable, de modo que JVM pueda permitir que el objeto de clase se serialice. Por qué la clase Object no está serializada, entonces ninguna de las clases necesita implementar la interfaz, después de todo, JVM serializa la clase solo cuando uso ObjectOutputStream, lo que significa que el control todavía está en mis manos para permitir que la JVM serialice.
La razón por la cual la clase Object no es serializable de manera predeterminada en el hecho de que la versión de la clase es el problema principal. Por lo tanto, cada clase que esté interesada en la serialización debe marcarse como Serializable explícitamente y proporcionar un número de versión serialVersionUID.
Si serialVersionUID no se proporciona, obtenemos resultados inesperados al deserializar el objeto, es por eso que JVM arroja InvalidClassException si serialVersionUID no coincide. Por lo tanto, cada clase debe implementar la interfaz Serializable y proporcionar serialVersionUID para asegurarse de que la clase presentada en ambos extremos sea idéntica.