2010-12-15 15 views
6

He leído que, en general, las clases abstractas no se deben hacer Serializable en Java. Las subclases deben ser serializables (con métodos de lectura, escritura personalizados si es necesario, por ejemplo, cuando las clases abstractas tienen campos).¿Por qué no serializar clases abstractas en Java?

¿Cuál es la razón detrás de esto? ¿Por qué se considera mal diseño?

Update1: Tengo una clase abstracta con algunos campos y tres subclases. A partir de ahora, estoy usando el siguiente enfoque.

He hecho todas las subclases serializables con métodos de lectura, escritura personalizados. En la clase abstracta tengo los siguientes métodos.

void writeFields(ObjectOutputStream out)throws IOException { .... } 

void readFields(ObjectInputStream in) throws IOException, ClassNotFoundException{ ... } 

En la lectura personalizada, escribir métodos de las subclases que llamo a estos métodos (de) serializar los campos de la clase abstracta. ¿Es este enfoque correcto? ¿O hay un mejor enfoque diferente?

Actualización 2: Tomé el consejo de Tom e hice mi clase abstracta Serializable. (Quiero que todas las subclases sean Serializables y tengo datos en la clase abstracta) Esto es un lado, pero solo para completar la historia Estoy usando reflection to change final fields as advised by Jeremy Manson.

+0

Esta pregunta se aplica a CUALQUIER lenguaje orientado a objetos. –

Respuesta

1

No sé si es necesariamente un mal diseño. La serialización es efectivamente un problema de implementación (tenga en cuenta que Josh Bloch no está de acuerdo conmigo), por lo que no tiene sentido para las interfaces. Si la clase abstracta tiene estado, entonces querrá que sea serializable. Si no tiene estado, no hay realmente ninguna razón para hacerlo.

Tomemos un ejemplo. java.security.cert.Certificate es una clase serializable abstracta, con un campo serializable "type". Si no fuera serializable, no sería posible serializar una subclase y establecer ese campo. Serías forzado a un hackeo.

Tenga en cuenta que java.io.Serializable es un truco. No debería haber sido una interfaz. Una anotación (o evolución del lenguaje como transient) hubiera sido más apropiada.

Como siempre, es mejor preferir la composición a la herencia y no hacer una serialización aleatoria de clase.

+0

Por favor, vea la pregunta actualizada. – athena

+0

@athena Realmente no quieres métodos así en una API. –

+0

¿Por qué no? Quiero que todas las subclases sean Serializables. La clase abstracta tiene campos. En esta situación, ¿es mejor hacer la clase abstracta Serializable (con métodos de escritura de lectura personalizados)? – athena

3

Tomemos la posición opuesta. Si tuviera que des-serializar el objeto, ¿cuál sería su tipo?

Por definición, no se puede crear una instancia de una clase abstracta. Si puedes serializarlo, eso implica que también se puede deserializar y eso te daría una instancia de la clase abstracta. Eso contradice la definición de una clase abstracta y, por lo tanto, no se puede hacer.

+0

+1, estaba a punto de decir lo mismo de manera un poco diferente, pero su respuesta lo ilustra de manera mucho más sucinta de lo que yo hubiera dicho. –

+3

Si deserializó el objeto, su clase sería la misma que el objeto que se serializó (dar o tomar 'writeReplace' /' readResolve'). –

+1

Creo que su argumento es defectuoso. No es posible instanciar una clase abstracta. Por lo tanto, nunca es posible que necesite deserializar una clase de abstracción. Cualquier deserialización de una clase abstracta estará en el contexto de una clase concreta derivada, lo que significa que la clase se conoce en el punto de deserialización. – DwB

5

Creo que la razón es que si una clase abstracta implementa Serializable, no hay forma de decir que un subtipo NO debe ser serializable. Es mejor dejar que cada tipo concreto se declare por sí mismo ...

+0

+1. La API de colecciones es un buen ejemplo para eso. – Bozho

+0

Quiero que todas las subclases sean serializables. La clase abstracta tiene campos. En esta situación, ¿es mejor hacer la clase abstracta Serializable? – athena

+0

mirando el marco de la colección - no;) AbstractList no es serializable. Pero no es una gran diferencia de todos modos. – Bozho

0

Es solo un mal diseño porque es una decisión forzada, ¿y si quieres una subclase que tenga miembros no serializables?

Es por eso.

E.g. La lista no es serializable, pero cada implementación de lista principal es.(Sé que la lista es una interfaz, pero una clase abstracta sin miembros =/= una interfaz)

Cuestiones relacionadas