2010-09-07 22 views
7

Proprio come dice il titolo, c'è un modo per verificare se un oggetto è serializzabile e, in caso contrario, renderlo così in fase di esecuzione?Riesci a rendere un oggetto serializzabile in fase di runtime?

+0

Se oggetto non è serializzabile, potrebbe essere per una buona ragione: per esempio, non ha molto senso per serializzare connessione al database. –

+1

Un formato di serializzazione che non è la serializzazione degli oggetti Java funziona? Sto pensando a una soluzione che utilizza la riflessione e JSON o XML per serializzare l'oggetto. Da altri commenti sembra che la tua esigenza sia quella di trasformare l'oggetto in una stringa e questo lo porterebbe a termine. –

+0

Questa domanda è davvero ampia, soprattutto perché non menziona tutti i vincoli di progettazione. (Ad esempio, è necessario un formato di serializzazione delle stringhe.) – jpaugh

risposta

11

Risposta breve - no.

Risposta più lunga - sì, utilizzando la manipolazione del codice byte, ad esempio con asm. Ma dovresti davvero considerare se è necessario. La serializzazione è una cosa seria (Effective Java ha un intero capitolo sulla serializzazione)

Btw, non ci sono alternative alla serializzazione binaria, che non richiedono l'oggetto che implementa Serializble (come sottolineato da Jacob nei commenti):

  • XML - java.beans.XMLEncoder.encode(..) è la versione XML di ObjectOutputStream
  • JSON - framework come Jacskon, GSON consentono di serializzare un oggetto con una linea.
+0

+1 per includere gli avvisi appropriati. – DJClayworth

1

Come altri hanno detto ... Breve risposta è No.

È assolutamente possibile aggiungere un'interfaccia per qualsiasi vecchio oggetto in fase di esecuzione utilizzando gli oggetti proxy come descritto al http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html. Ciò include anche java.io.Serializable. Tuttavia, affinché un oggetto proxy sia utile, deve mantenere un riferimento interno all'oggetto originale, che nel tuo caso non implementa Serializable. L'unico modo in cui il tuo oggetto proxy può essere serializzato è rendere il riferimento interno all'oggetto originale un campo transitorio e questo non ti farebbe molto bene.

Inoltre, dopo aver esaminato i tuoi commenti, sembra che la serializzazione java non sia assolutamente quella che desideri e in realtà desideri semplicemente serializzare su un formato di stringa. Altri hanno suggerito varie soluzioni, ma IMO se vuoi la minima quantità di problemi, vai con XStream: http://x-stream.github.io/tutorial.html.

+0

I proxy vengono creati tramite l'interfaccia, non su una classe. – Bozho

+0

@Bozho - quella parte è dettagliata nella documentazione a cui mi sono collegato. Richiederebbe alcuni cambiamenti nella sua base di codice se non sta già usando Interface per polimorficamente (sp?) Riferimento ai suoi oggetti. – whaley

+1

Il suo oggetto originale sarebbe un membro di InvocationHandler, anch'esso serializzato, che fallirà. – Bozho

0

Whoa. Perché dovresti averne bisogno per essere controllato in fase di runtime? Non è più facile assicurarlo al momento della compilazione? Usando un codice proprio come questo.

public void someMethod(Serializable serializable){ 
} 

Oppure puoi renderlo più complesso.

public interface SerializableInterface implements Serializable{ 
// bla-bla 
} 

public void someMethod(SerializableInterface serializable){ 
} 
0

Oltre a buone risposte esistenti, un'altra domanda è se si specificamente bisogno di Java Serializable per quadro specifico, o solo bisogno di essere in grado di oggetti serializzatore. Per quest'ultimo ci sono molte molte più scelte rispetto a quella predefinita di JDK; e per molti casi d'uso le alternative sono molto migliori di quelle di JDK.

Se non si necessita specificamente di JDK uno, utilizzare la serializzazione basata su JSON o XML è spesso una buona scelta.

+0

La ragione per cui sto guardando la serializzazione è per un progetto che vorrei convertire un oggetto in una stringa (attraverso un array di byte) per l'archiviazione e la trasmissione dove è necessario che sia una stringa a causa di fattori esterni. Ho visto diversi esempi di come utilizzare la serializzazione per convertire in un flusso di byte per catturare l'oggetto come una stringa alla fine, ma nulla su cosa fare se l'oggetto non è serializzabile. Capisco la necessità che certi oggetti non vengano serializzati, ma in questo caso sarebbe qualcosa lasciato alla discrezione dello sviluppatore. –

+0

Ok, allora NON vuoi usare seriali JDK. Vorrei raccomandare l'uso della serializzazione JSON (come Jackson, vedi http://wiki.fasterxml.com/JacksonInFiveMinutes). Il risultato è più leggibile e molto meno fragile. Il problema principale con Serializable è che il versioning è molto difficile, quindi è un anti-pattern per persistere dei risultati (leggi la spiegazione di Josh Bloch, per esempio). Non è nemmeno leggibile (a differenza di xml o json). Non c'è niente di sbagliato nel serializzare le cose di per sé, ma Serializable è raramente nel modo giusto. – StaxMan

0

Controllo in fase di esecuzione? Sicuro. "if (someObject instanceof Serializable) ...".

Si desidera modificare la definizione di un oggetto in fase di esecuzione? Raramente c'è una buona ragione per volerlo fare. Forse c'è un modo per farlo con la riflessione, ma non ho mai avuto una ragione per voler fare una cosa del genere. Cosa stai cercando di realizzare?

0

Se qualcuno ha davvero davvero bisogno di manipolare con bytecode in runtime.Con biblioteca Javassist si può fare questo:

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