martedì 13 dicembre 2011

Facile clonazione profonda di Serializable e non serializzabile oggetti in Java

Frequenti gli sviluppatori si basano su librerie partito 3d per evitare di reinventare la ruota, in particolare nel mondo Java, con progetti come Apache e primavera così diffusi. Quando si tratta di questi quadri, che spesso hanno poco o nessun controllo del comportamento delle loro classi. 
Questo a volte può portare a problemi. Per esempio, se si vuole clonare profondo un oggetto che non fornisce un metodo adeguato clone, quali sono le opzioni, a meno di scrivere un mucchio di codice?
Clone tramite serializzazione
L'approccio più semplice è quello di clonare, approfittando di un oggetto da Serializable. Apache Commons fornisce un metodo per fare questo, ma per completezza, il codice per farlo da soli è al di sotto anche.
01.@ SuppressWarnings "deselezionata" )
02.pubblico statico   cloneThroughSerialize T (T t) getta Exception {
03.bos ByteArrayOutputStream = nuovo ByteArrayOutputStream ();
. 04serializeToOutputStream (t, BOS);
. 05byte [] bytes = bos.toByteArray ();
06.ObjectInputStream ois = nuovo ObjectInputStream ( nuovo ByteArrayInputStream (byte));
07.ritorno (T) ois.readObject ();
08.}
09. 
10.private static void serializeToOutputStream (Serializable ser, OutputStream os)
11.lancia IOException {
12.ObjectOutputStream OOS = nullo ;
13.tentare {
14.OOS = nuovo ObjectOutputStream (os);
15.oos.writeObject (SER);
16.oos.flush ();
17.infine {
18.oos.close ();
19.}
20.}
21. 
22./ / utilizzando il nostro metodo personalizzato
. 23oggetti clonati = cloneThroughSerialize (someObject);
24. 
25./ / o con Apache Commons
26.clonato = org.apache.commons.lang. SerializationUtils.clone (someObject);
Ma cosa succede se la classe si vuole clone non è Serializable e non abbiamo alcun controllo sul codice sorgente o non può farlo Serializable?
Opzione 1 - Biblioteca Clonazione Java profondo
C'è una biblioteca bel po 'che può profonda clonare qualsiasi oggetto Java - la clonazione . Si avvale delle funzionalità di Java riflessione eccellente per fornire versioni ottimizzate profondo clonato degli oggetti.
1.Cloner cloner = nuovo Cloner ();
2.Object clonato = cloner.deepClone (someObject);
Come potete vedere, è molto semplice ed efficace, e richiede il codice minimo. Ha alcune abilità più avanzate al di là di questo semplice esempio, che potete verificare qui .
Opzione 2 - Clonazione JSON
Che dire se non siamo in grado di introdurre una nuova libreria per la nostra base di codice? Alcuni di noi affrontare i processi di approvazione per introdurre nuove librerie, e non può essere la pena per un caso d'uso semplice.
Beh, finchè abbiamo qualche modo per serializzare e ripristinare un oggetto, possiamo fare una copia completa. JSON è comunemente usato, quindi è un buon candidato, poiché la maggior parte di noi usa una libreria JSON o in un altro.
La maggior parte delle librerie JSON in Java hanno la possibilità di serializzare in modo efficace qualsiasi POJO senza alcuna configurazione o la mappatura necessaria. Questo significa che se avete una libreria JSON e non può o non vuole introdurre più librerie per fornire la clonazione profonda, è possibile sfruttare una libreria esistente JSON per ottenere lo stesso effetto. Nota questo metodo sarà più lento rispetto ad altri, ma per la stragrande maggioranza delle applicazioni, questo non causerà alcun problema di prestazioni.
Di seguito è riportato un esempio utilizzando la GSON biblioteca.
1.@ SuppressWarnings "deselezionata" )
2.pubblico statico   cloneThroughJson T (T t) {
3.Gson gson = nuovo Gson ();
4.stringa JSON gson.toJson = (t);
5.ritorno (T) gson.fromJson (JSON, t.getClass ());
6.}
7./ / ...
8.Object clonato = cloneThroughJson (someObject);
Si noti che questo è probabilmente solo a lavorare, se l'oggetto copiato ha un costruttore senza argomenti predefiniti. Nel caso di GSON, è possibile utilizzare un creatore esempio per aggirare questo. Altri framework sono concetti simili, in modo da poter utilizzare che se si colpisce un problema con una classe immodificabile avendo non avendo il costruttore predefinito.
Conclusione
Una cosa che si consiglia è che per tutte le classi è necessario clonare, è necessario aggiungere alcune unit test per assicurarsi che tutto si comporta come previsto. Questo può impedire le modifiche alle classi (ad esempio versioni di librerie aggiornamento) da rompere l'applicazione senza la vostra conoscenza, soprattutto se si dispone di un ambiente continuo di integrazione impostato.
Ho delineato un paio di metodi per clonare un oggetto al di fuori di casi normali, senza alcun codice personalizzato. Se avete già utilizzato altri metodi per ottenere lo stesso risultato, si prega di condividere.

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.