2010-01-22 24 views
6

Hay una clase que quiero serializar, e implementa Serializable, pero uno de los objetos que contiene no implementa Serializable.En java, ¿es posible agregar la interfaz Serializable a la clase que no la tiene en tiempo de ejecución?

¿Hay alguna manera de modificar la clase en tiempo de ejecución para que implemente la interfaz Serializable para poder serializarla? No puedo cambiarlo en tiempo de compilación porque es una biblioteca de terceros.

Tal vez tendría que usar algún tipo de escritor de códigos de bytes o algo así?

EDITAR: Tanto la clase que contiene como la clase contenida están en la biblioteca de terceros, así que no creo que pueda marcar algo como transitorio. La clase contenedora es marcada como serializable, pero contiene un objeto que no lo es.

Estoy bien escribiendo un método de serialización personalizado para la clase, aunque no estoy seguro de cómo lo haría, ¿tendría que usar la reflexión para obtener los valores de las variables privadas?

Respuesta

5

Leyendo el Javadoc para Serializable, veo:

clases que requieren un manejo especial durante la serialización y proceso de deserialización debe implementar métodos especiales con estas exactas firmas:

private void writeObject(java.io.ObjectOutputStream out) 
    throws IOException 
private void readObject(java.io.ObjectInputStream in) 
    throws IOException, ClassNotFoundException; 
private void readObjectNoData() 
    throws ObjectStreamException; 

que puede usar para serializar manualmente los campos no cooperativos. Podría considerar usar ASM, pero parece difícil de creer que sea una solución sostenible.

+0

Usar la interfaz Externalizable http://java.sun.com/j2se/1.3/docs/api/java/io/Externalizable.html –

+0

La clase contenedora también está en la biblioteca de terceros, así que no creo que pueda agrega esos métodos a él. – Kyle

+0

Entonces supongo que es hora de aprender asm. – bmargulies

3

Los campos se pueden omitir con el modificador transient. Se pueden agregar datos adicionales a la secuencia al proporcionar los métodos readObject y writeObject. Las clases se pueden subclasificar para hacerlas serializables (aunque será necesario administrar los datos de la superclase), o usar un proxy serie (ver Java efectivo).

0

Si una clase no está marcada como Serializable, podría ser una buena razón (tome como ejemplo las conexiones a la base de datos). Entonces, antes que nada, aclare su identidad si realmente necesita serializar ese objeto también. Si solo necesita serializar el objeto circundante, puede considerar marcar el objeto contenido como transitorio.

1

En primer lugar, ¿usted realmente necesita hacer esto? Tal vez la clase en la biblioteca de terceros no sea serializable por diseño. Incluso si se trata de una omisión en lugar de una decisión deliberada, es bastante fácil escribir un método de serialización personalizado en una clase de ayuda. Si tiene para hacer esto (como tuve que hacerlo, para algo similar). Eche un vistazo al Javassist. Se puede hacer algo como esto:

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("mypackage.MyClass"); 
cc.addInterface(pool.get("java.io.Serializable")) 

EDIT: Se puede utilizar una API de serialización de terceros, como XStream en lugar de hacer todo el trabajo sucio a ti mismo.

+0

Acerca de escribir el método de serialización personalizado en una clase de ayuda: ¿Cómo haría esto? ¿Necesito usar la reflexión para obtener los valores de las variables privadas? – Kyle

+0

LOL. Esta respuesta ya es el tercer resultado de Google para la "tercera parte de Java Server de serialización" 32 minutos después de que se hizo la pregunta. –

0

Puede usar java.lang.reflect.Proxy para agregar la interfaz Serializable a instancias de objeto sobre las que no tiene control de ciclo de vida (es decir, no puede subcategorizarlas) y hacer que se serialicen de esta manera. Pero aún no podrás leerlos sin otro truco (es decir, presentar una clase sustituta).

Recomendaría buscar una alternativa al mecanismo Serializable de Java en general. Está bastante roto por diseño de varias maneras.

+0

Es extraño que tantos desarrolladores estén completamente de acuerdo con la serialización de "roto por diseño" de Java. Hacer rodar su propia serialización es una solución horrible, muchas bibliotecas/frameworks estándar de Java hacen uso de Serializable, ¿se supone que debe programar una solución para cada una de ellas? – Nate

Cuestiones relacionadas