Domanda

Perché non è la serialVersionUID generato automaticamente? Stavo correndo in un problema su un server di applicazioni in cui a quanto pare è stata memorizzata nella cache una vecchia classe.

È stato utile?

Soluzione

serialVersionUID non viene generato automaticamente, perché è pericoloso. Quando serialVersionUID è impostato, esso implica che due versioni di una classe sono compatibili rispetto alla serializzazione.

Immaginate di avere una classe chiamata Foo, e ha non serialVersionUID (il default), e si serializzare un'istanza di Foo in un file. In seguito, si aggiungono alcuni nuovi membri alla classe Foo. Se si tenta di deserializzare l'oggetto Foo dal file, si otterrà un errore di serializzazione affermando che gli oggetti sono incompatibili. Essi sono incompatibili, questo è quello che vuoi ed è l'impostazione predefinita. Essi sono incompatibili, perché i nuovi membri della classe Foo non possono essere inizializzati dalla vecchia istanza serializzato di Foo.

Ora, si potrebbe dire: "Non mi interessa, nella mia richiesta è accettabile per i campi da non inizializzata". Se che davvero è il caso, è possibile impostare il serialVersionUID della classe nuovo Foo essere lo stesso come il vecchia classe Foo. Questo vi dirà Java che gli oggetti sono compatibili per quanto riguarda serializablity, e Java non si lamenterà quando si deserializzare l'istanza Foo nella nuova classe Foo (ma i nuovi campi sarà ancora inizializzata).

Se si sta creando una nuova classe per la prima volta, e si imposta la serialVersionUID, si sta entrando in un contratto . Tale contratto è, "Per tutte le versioni future di questa classe con lo stesso serialVersionUID, mi garantirà che siano compatibili con il rispetto per lo stato e la serializzazione" .

Se si modifica una classe, e si esplicitamente da Disallow deserializzazione di vecchie versioni, è possibile modificare la serialVersionUID ad un nuovo valore. Ciò causerà un'eccezione per essere gettato se un vecchio oggetto si cerca di essere deserializzato in una nuova istanza della classe.

Altri suggerimenti

Si è generato automaticamente, in base alla struttura della classe. Se cambia la struttura, l'id viene rigenerata (secondo la la serializzazione specifica si tratta di un hashof la classe).

Quindi è meglio definire un serialVersionUID esplicito.

Se si utilizza Eclipse come IDE, è possibile fare clic destro su l'avviso circa la mancanza serialVersionUID e avrete due opzioni:

1) Definire il predefinito Eclipse, che ha il valore 1L; o
2) Definire un valore generato casualmente lungo

Se avete a cuore versioni di oggetti serializzati, avrete bisogno di rigenerarsi manualmente un nuovo valore ogni volta che si modifica la classe. Il Javadoc per l'interfaccia Serializable ha questo da dire su quello che succede se non si dichiara un serialVersionUID a tutti:

  

Se una classe serializzabile non dichiara esplicitamente un serialVersionUID, quindi il runtime serializzazione calcolerà un valore serialVersionUID predefinito per quella classe sulla base di vari aspetti della classe, come descritto nella Java (TM) Object serializzazione Specification. Tuttavia, si raccomanda che tutte le classi serializzabili espressamente dichiarano valori serialVersionUID, poiché il calcolo predefinito serialVersionUID è altamente sensibile ai dettagli di classe che possono variare a seconda implementazioni compilatore, e possono quindi favorire InvalidClassExceptions imprevisti durante deserializzazione. Pertanto, al fine di garantire un valore serialVersionUID coerente tra le diverse implementazioni java compilatore, una classe serializzabile deve dichiarare un valore serialVersionUID esplicito.

In pratica, ho scoperto che anche se si inizia con il codice sorgente di identica su due o più macchine (controllato da Subversion, per esempio) in cui è stato serialVersionUID undefined in una classe, il valore generato dal compilatore nella classe è diverso su ogni macchina quando il codice viene compilato. Ciò può causare confusione errori durante lo sviluppo.

Se sei sicuro che non avrai mai avere una situazione in cui si dispone di oggetti serializzati stantio che sono out-of-sync con una nuova versione della classe (o due JVM mandando out-of-sync serializzato oggetti tra di loro , forse attraverso una rete o di connessione socket) poi basta impostare un valore di 1L per serialVersionUID e lasciarlo così per sempre.

http: // download-LLNW .oracle.com / JavaSE / 6 / docs / api / java / io / Serializable.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top