2013-07-23 22 views
11

In Java, le interfacce Collection non si estendono Serializable per diversi buoni motivi. Inoltre, le implementazioni più comuni di queste interfacce implementano Serializable.Java: come garantire le collezioni serializzabili

Quindi gli oggetti che implementano una delle interfacce Collection sono serializzabili se l'implementazione stessa è serializzabile (che di solito è il caso) e se gli oggetti nella raccolta sono tutti serializzabili.

Ma come posso garantire che queste due condizioni siano soddisfatte? Non voglio incappare in un errore di runtime dal momento che il compilatore può verificare queste condizioni. Sto pensando di qualche interfaccia evidente come (vetrina per la lista-interfaccia):

public interface SerializableList<T extends Serializable> extends Serializable, List<T> {} 

Mi chiedo se nessun altro si trova ad affrontare questo problema e si avvicinò con questa soluzione facile. Fino ad ora non ero in grado di trovare alcuna soluzione o discussione su questo, il che mi fa dubitare della mia idea.

+0

Puoi fare il tuo riferimento a 'List' come -' List ', se comprendo correttamente la tua domanda. Non è necessario implementare la propria interfaccia. –

+0

Il compilatore non può verificarlo. Ogni classe che implementa Serializable potrebbe contenere un campo non temporaneo, non serializzabile, che porterebbe a un'eccezione di runtime. E una ArrayList potrebbe essere serializzabile se gli oggetti reali che contiene sono serializzabili. Se è davvero importante, usa i test unitari. –

+1

@RohitJain: la proposta garantisce solo che gli oggetti nell'elenco siano serializzabili, ma non l'implementazione Elenco stessa. – MrD

risposta

6

Quello che in sostanza chiedere è una definizione di tipo unione di due tipi:

<type-def> a = null;

Quello che vi serve è un sostituto di <type-def> con una specifica, facendo in modo che l'oggetto a cui fa riferimento a implementa sia Serializable come bene come Collection<? extends Serializable>. Tale definizione di tipo non è supportata dal linguaggio Java.

Come già scritto, la soluzione più ovvia potrebbe essere quella di dichiarare la propria interfaccia, unendo questi due altre interfacce:

interface SerializableCollection<T extends Serializable> extends Collection<T>, Serializable {}

sembra ok, fino a quando si tenta qualcosa di simile:

SerializableCollection<String> a = new ArrayList<String>();

Questo tuttavia non verrà compilato. Anche se ArrayList<String> implementa sia Collection<? extends Serializable> e Serializable, la classe non implementa SerializableCollection<String>.

Ora, è possibile se si desidera, aggirare anche questo problema dichiarando una nuova classe:

SerializableArrayList<T extends Serializable> extends ArrayList<T> implements SerializableCollection<T> {}

Ora avete essenzialmente unito tutto il necessario e sarebbe in grado di soddisfare il requisito originale:

SerializableCollection<String> a = new SerializableArrayList<String>();

Vale la pena? Nel tuo caso, devi decidere, ma direi di no.La mia argomentazione è che, dal momento che il marcatore Serializable è solo un'etichetta non formale, assicurando che sia la tua raccolta sia il suo contenuto implementino Serializable non garantisce ancora che la raccolta e il suo contenuto in realtà possano essere serializzati come.

+1

Grazie. Penso che tutto sia chiaro per me ora. Come affermato da te e JB Nizet, non posso fare affidamento sul fatto che gli oggetti che implementano l'interfaccia 'Serializable' sono veramente serializzabili (è un peccato). Penso che questo sia il punto: ne vale la pena? Ci penserò se è applicabile nel mio caso. – MrD

6

Serializable non è una grande interfaccia. Dovrebbe essere un'annotazione, se erano disponibili quando è stata implementata.

Come gestireste uno List di un numero Serializable. Dovresti assicurarti che nessun oggetto non sia serializzabile transitivamente lungo il grafico dell'oggetto. Non tutti gli oggetti che implementano Serializable possono effettivamente essere serializzati.

+0

Quindi non c'è modo di fare un controllo della compilazione per questo? –

+0

'interfaccia SerializableCollection > {} 'si può fare qualcosa del genere? –

+1

Un 'Elenco' di oggetti che non sono' Serializable' non può essere aggiunto a 'SerializableList' poiché questo' List' non implementa 'Serializable'. Naturalmente, potrei aggiungere un 'ArrayList' (che è serializzabile) contenente alcuni oggetti non serializzabili - ma solo se lo uso come un tipo raw. Se è parametrizzato, il compilatore dovrebbe lamentarsi di questo. – MrD

0

Un approccio per la clonazione di una collezione e contenute oggetti è

import org.apache.commons.lang3.SerializationUtils; 
... 
ClonedArrayList = SerializationUtils.deserialize(SerializationUtils.serialize(OriginalArrayList)) 

(ad esempio tramite uso ArrayList <Tipo> (collezione) perché SerializationUtils necessitano l'interfaccia Serializable)

saluti, Gunnar

Problemi correlati