Trabajamos mucho con la serialización y tener que especificar una etiqueta serializable en cada objeto que usamos es una 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 serialización robusta una vez que agrega implements Serializable
, ¿por qué no hicieron que todo se serializara y eso es todo?
¿Qué me estoy perdiendo?
java
serialization
Yoni Roit
fuente
fuente
Respuestas:
La serialización está plagada de trampas. El soporte de serialización automática de este formulario hace que las clases internas formen parte de la API pública (razón por la cual javadoc le brinda las formas persistentes de clases ).
Para la persistencia a largo plazo, la clase debe poder 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 provocar problemas de seguridad. Al poder serializar cualquier objeto al que tenga una referencia, una clase puede acceder a datos que normalmente no podría (analizando los datos de bytes resultantes).
Hay otros problemas, como que la forma serializada de las clases internas no está bien definida.
Hacer todas las clases serializables exacerbaría estos problemas. Consulte Effective Java Second Edition , en particular, el artículo 74: Implementar serializable con criterio .
fuente
Creo que tanto la gente de Java como la de .Net se equivocaron esta vez, habría sido mejor hacer todo serializable de forma predeterminada y solo necesitar marcar aquellas clases que no se pueden serializar de forma segura.
Por ejemplo, en Smalltalk (un lenguaje creado en los 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) no hace mágicamente 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 ello. la serialización es como está ahora.
Creo que fue una mala decisión tomada por los diseñadores o la serialización fue una ocurrencia tardía, o la plataforma nunca estuvo lista para realizar la serialización por defecto en todos los objetos de manera segura y consistente.
fuente
Serializable
truco es solo otra decisión incorrecta que se tomó hace una o dos décadas, y una adición más a la molestia cuando se trata de Java puro, como algunas fallas en la colección y el procesamiento de cadenas en la biblioteca estándar. Felizmente está Kryo, pero es dependencia y hay que encontrarlo primero. Así es como debería haberse realizado la serialización integrada.No todo es genuinamente serializable. Tome una conexión de red, por ejemplo. Puede serializar los datos / estado de su objeto de socket, pero la esencia de una conexión activa se perdería.
fuente
implements NotSerializable
:)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 de forma predeterminada, incluso si cuesta un poco hacer que las cosas sean serializables.
La serialización agrega restricciones y problemas potenciales ya que la compatibilidad de la estructura no está asegurada. Es bueno que esté desactivado por defecto.
Debo 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 dedicaría a hacer que la clase se serializara adecuadamente eclipsa el costo de agregar la interfaz.
fuente
Para algunas clases, especialmente aquellas que representan algo más físico como un archivo, un socket, un hilo o una conexión de base de datos, no tiene ningún sentido serializar instancias. Para muchos otros, la serialización puede ser problemática porque destruye las restricciones de unicidad o simplemente lo obliga a lidiar con instancias de diferentes versiones de una clase, lo que quizás no desee.
Podría decirse que podría haber sido mejor hacer que todo se serializara de forma predeterminada y que las clases no se serializaran a través de una interfaz de palabra clave o marcador, pero aquellos que deberían usar esa opción probablemente no pensarían en ello. Tal como está, si necesita implementar Serializable, una Excepción se lo dirá.
fuente
Creo que la idea fue asegurarse de que usted, como programador, sepa que su objeto puede ser serializado.
fuente
Aparentemente, todo fue serializable en algunos diseños preliminares, pero debido a preocupaciones de seguridad y corrección, el diseño final terminó como todos sabemos.
Fuente: ¿Por qué las clases deben implementar Serializable para poder escribirse en un ObjectOutputStream? .
fuente
Tener que declarar explícitamente que las instancias de una determinada clase son serializables, el lenguaje te obliga a pensar si debes permitir eso. Para objetos de valor simple, la serialización es trivial, pero en casos más complejos es necesario pensar realmente las cosas.
Con solo confiar en el soporte de serialización estándar de la JVM, se expone a todo tipo de problemas desagradables de versiones.
La singularidad, las referencias a recursos "reales", temporizadores y muchos otros tipos de artefactos NO son candidatos para la serialización.
fuente
Lea esto para comprender la Interfaz serializable y por qué debemos hacer que solo unas pocas clases sean serializables y también nos ocuparemos de dónde usar la palabra clave transitoria en caso de que queramos eliminar algunos campos del procedimiento de almacenamiento.
http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/
fuente
Bueno, mi respuesta es que esto no es por una buena razón. Y por sus comentarios puedo ver que ya lo aprendió. Otros lenguajes intentan felizmente 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 debe hacer es leer todas las propiedades de su clase de terceros usted mismo. O, si esa es una opción para usted: descompilar, poner la maldita palabra clave allí y volver a compilar.
fuente
Hay algunas cosas en Java que simplemente no se pueden serializar porque son específicas del tiempo de ejecución. Cosas como transmisiones, subprocesos, tiempo de ejecución, etc. e incluso algunas clases de GUI (que están conectadas al sistema operativo subyacente) no se pueden serializar.
fuente
Si bien estoy de acuerdo con los puntos mencionados en otras respuestas aquí, el problema real 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 campos existentes es un compromiso bastante importante para el autor de una biblioteca! Mantener la compatibilidad con la API ya es bastante complicado.
fuente
Una clase que debe conservarse en un archivo u otro medio tiene que implementar una interfaz serializable, de modo que JVM pueda permitir que el objeto de la clase sea serializado. 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 se serialice.
La razón por la que la clase Object no se puede serializar de forma predeterminada es 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 no se proporciona serialVersionUID , obtenemos resultados inesperados al deserializar el objeto, es por eso que JVM arroja InvalidClassException si serialVersionUID no coincide. Por lo tanto, cada clase tiene que implementar una interfaz serializable y proporcionar serialVersionUID para asegurarse de que la clase presentada en ambos extremos sea idéntica.
fuente