Domanda

Quando classe implementa Serializable in Eclipse, ho due opzioni: aggiungere serialVersionUID(1L) predefinito o serialVersionUID(3567653491060394677L) generato. Credo che prima è più fresco, ma molte volte ho visto persone che utilizzano la seconda opzione. C'è qualche motivo per generare long serialVersionUID?

È stato utile?

Soluzione

Per quanto posso dire, che sarebbe solo per compatibilità con le versioni precedenti. Questo sarebbe solo utile se trascurato di utilizzare un serialVersionUID prima, e poi ha fatto un cambiamento che si sa dovrebbe essere compatibile noreferrer ma che provoca la serializzazione a rompere.

Vedere la Java serializzazione Spec ulteriori dettagli.

Altri suggerimenti

Lo scopo della versione serializzazione UID è quello di tenere traccia delle diverse versioni di una classe al fine di eseguire la serializzazione degli oggetti validi.

L'idea è quella di generare un ID che è unico per una certa versione di una classe, che viene poi cambiato quando ci sono nuovi dettagli aggiunti alla classe, come ad esempio un nuovo campo, che possa modificare la struttura dell'oggetto serializzato .

Sempre utilizzando lo stesso ID, come ad esempio 1L significa che in futuro, se la definizione di classe è cambiato che provoca modifiche alla struttura dell'oggetto serializzato, ci sarà una buona probabilità che i problemi quando si cerca di deserializzare un oggetto.

Se l'ID viene omesso, Java sarà effettivamente calcolare l'ID per voi in base campi dell'oggetto, ma credo che è un processo costoso, in modo da fornire una manualmente migliorerà le prestazioni.

Ecco un paio di link ad articoli che discutono serializzazione e delle versioni di classi:

Il motivo principale per il generato uno sarebbe per renderlo compatibile con una versione esistente di classe che già si è protratto copie.

Il predefinito "lunga" della serialVersionUID è il valore predefinito come definito dalla Java Specification serializzazione , calcolata dal comportamento predefinito di serializzazione.

Quindi, se si aggiunge il numero di versione di default, la classe sarà (de-) serializzare più velocemente finché nulla è strutturalmente cambiato, ma si dovrà fare in modo che se si cambia la classe (aggiungere / rimuovere i campi) si anche aggiornare il numero di serie.

Se non c'è bisogno di essere compatibile con flussi di bit esistenti, si può semplicemente mettere 1L lì e incrementare la versione, se necessario, quando qualcosa cambia. Cioè, quando la versione di default serializzazione della classe mutato sarebbe diverso dalla versione di default della vecchia classe.

È assolutamente necessario creare un serialVersionUID ogni volta si definisce una classe che implementa java.io.Serializable. Se non lo fai, lo farà essere creati in modo automatico, ma questo è male. L'auto-generata serialVersionUID si basa sul metodo firme della vostra classe, in modo da se si modifica la classe in futuro di aggiungere un metodo (per esempio), deserializzazione le "vecchie" versioni della classe avrà esito negativo. Ecco cosa può accadere:

  1. Crea la prima versione della classe, senza definire il serialVersionUID.
  2. serializzare un un'istanza della classe in un negozio persistente; un' serialVersionUID viene generato automaticamente per voi.
  3. Modifica la tua classe per aggiungere un nuovo metodo, e ridistribuire l'applicazione.
  4. Il tentativo di deserializzare l'istanza che è stato serializzato nel passaggio 2, ma ora non riesce (quando dovrebbe avere successo), perché ha un diverse auto-generato serialVersionUID.

Se non si specifica un serialVersionUID poi Java rende al volo. Il serialVersionUID generato è quel numero. Se si cambia qualcosa nella tua classe che in realtà non rendere la vostra classe incompatibile con precedenti verisons serializzati, ma cambia l'hash, allora avete bisogno di utilizzare il generato molto-grande numero serialVersionUID (o il numero "atteso" dal messaggio di errore) . In caso contrario, se si sta tenendo traccia di tutto da soli, 0, 1, 2 ... è meglio.

Quando si utilizza serialVersionUID (1L) piuttosto che generare serialVersionUID (3567653491060394677L) si sta dicendo qualcosa.

Stai dicendo che sei sicuro al 100% che nessun sistema che sarà mai toccare questa classe che ha una versione serializzata non compatibile di questa classe con un numero di versione 1.

Se si può pensare di qualsiasi scusa per la sua serializzato cronologia delle versioni ad essere sconosciuto, che potrebbe essere difficile da dire con fiducia. Nella sua vita, una classe di successo sarà mantenuto da molte persone, vivono in molti progetti, e di soggiornare in molti sistemi.

È possibile agonizzare su questo. Oppure si può giocare alla lotteria sperando di perdere. Se si genera la versione che si dispone di una piccola possibilità che qualcosa vada male. Se si assume "Ehi scommetto che nessuno utilizzato ancora 1" le probabilità sono più grandi di minuscole. E 'proprio perché siamo tutti pensiamo 0 e 1 sono fresco che si hanno una maggiore probabilità di colpire loro.

-

Quando si genera serialVersionUID (3567653491060394677L) piuttosto che utilizzare serialVersionUID (1L) si sta dicendo qualcosa.

che stai dicendo le persone possono avere sia stato creato manualmente o generato altri numeri di versione nel corso della storia di questa classe e non si cura perché Longs sono impazzendo grandi numeri.

In entrambi i casi se non si conosce perfettamente la storia di numeri di versione utilizzata durante la serializzazione della classe in tutto l'universo di cui si ha o potrà mai esistere, si sta prendendo una possibilità. Se avete il tempo per assicurarsi il 100% 1 è AOK, andare per esso. Se questo è di molto lavoro, andare avanti e generare ciecamente il numero. È molto più probabile di vincere la lotteria che avere che vanno male. Se è così, fatemelo sapere e io ti compro una birra.

Con tutto questo parlare di giocare alla lotteria io vi ho dato l'impressione che serialVersionUID viene generata casualmente. Infatti fino a quando l'intervallo di numeri uniforme ogni possibile valore di un lungo che sarebbe bene. Tuttavia, in realtà è fatto in questo modo:

http://docs.oracle. com / JavaSE / 6 / docs / platform / serializzazione / spec / class.html # 4100

L'unica differenza che si ottiene con questo è che non bisogno di una fonte di casuale. Stai usando i cambiamenti nella classe stessa per cambiare il risultato. Ma secondo il principio dei cassetti c'è ancora una possibilità che potrebbe andare male e hanno una collisione. E 'solo incredibilmente improbabile. Quindi buona fortuna ottenere una birra fuori di me.

Tuttavia, anche se la classe sarà sempre e solo vivere in un sistema e una base di codice, pensando che incrementando il numero di mano ti dà zero possibilità di collisioni solo significa che non si capisce l'uomo. :)

Bene, serialVersionUID è un'eccezione alla regola che “i campi statici non ottengono serializzato”. ObjectOutputStream scrive ogni volta il valore della serialVersionUID nel flusso di output. ObjectInputStream legge indietro e se il valore letto dal flusso non è d'accordo con il valore serialVersionUID nella versione corrente della classe, poi getta l'InvalidClassException. Inoltre, se non c'è serialVersionUID dichiarato ufficialmente nella classe da serializzare, compilatore aggiunge automaticamente con un valore generato in base ai campi dichiarati nella classe.

Perché in molti casi di default id non è unica. così creiamo id per fare concetto unico.

Per aggiungere @ Davide Schmitts risposta, come regola generale vorrei sempre utilizzare il valore predefinito 1L di convenzione. Ho avuto solo per tornare indietro e modificare alcuni di loro un paio di volte, ma sapevo che quando ho fatto il cambiamento e aggiornato il numero predefinito di uno ogni volta.

A mia società attuale richiedono il numero di auto-generata in modo che io uso per convenzione, ma io preferisco il default. Il mio prendere è, se non è una convenzione in cui si lavora, utilizzare il valore di default, a meno che non si pensa sarete costantemente cambiando la struttura di voi classi serializzato per qualche motivo.

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