Domanda

Probabilmente sto rischiando alcuni voti negativi su questo.

Mi sembra che specificare esplicitamente serialVersionUID per le nuove classi sia sbagliato. Considera i due casi di non cambiarlo quando ha il layout avrebbe dovuto essere cambiato e cambiarlo quando non dovrebbe.

Non cambiare quando avrebbe dovuto essere cambiato si verifica quasi solo quando è esplicito. In questo caso, si ottengono alcuni bug molto sottili e difficili da trovare. Soprattutto durante lo sviluppo, quando il layout della classe cambia spesso. Ma se non è stato specificato esplicitamente, cambierà e la deserializzazione si spezzerà rumorosamente, probabilmente risolto eliminando il repository.

Cambiarlo quando non avrebbe dovuto accaderebbe quasi solo quando è implicito. Questo è il raro caso in cui il layout della classe è cambiato ma vogliamo ancora deserializzare dai vecchi BLOB serializzati. Questo sarà probabilmente rilevato durante il QA ( Errori strani dopo l'aggiornamento da 5.2 a 5.2.1, vedi stack stack allegato ) e può essere banalmente risolto impostando un valore esplicito.

Commenti?

È stato utile?

Soluzione

Cambiare quando non dovrebbe accadere per ragioni diverse dalle modifiche al layout della classe - il problema è che dipende dall'implementazione del compilatore. Se esegui il debug con Eclipse ma esegui build di produzione con javac, potresti finire con due insiemi di dati incompatibili.

Altri suggerimenti

Al mio lavoro proibiamo esplicitamente di specificare serialVersionUID, proprio a causa dei problemi che si presentano.

Inoltre, le classi che persistiamo vengono utilizzate solo per archiviare dati senza logica all'interno, quindi l'unico modo in cui cambiano è a causa della modifica dei membri dei dati.

per enfatizzare ulteriormente ciò che John Skeet ha detto e per contraddire il commento:

" Se non ti serve (ad esempio, devi sempre serializzare e deserializzare con la stessa versione di classe), puoi saltare in sicurezza la dichiarazione esplicita "

Anche se non stai serializzando a lungo termine e stai utilizzando la stessa versione di classe, potresti avere ancora problemi . se stai scrivendo il codice client-server e il codice client potrebbe essere eseguito con una versione / implementazione jvm diversa rispetto al server, potresti avere gli stessi problemi con serialversionuids incompatibili.

per riassumere, il solo è tempo " sicuro " non specificare serialversionuids è quando non si sta serializzando a lungo termine e si garantisce che tutti i consumatori dei dati serializzati useranno la stessa implementazione jvm e la stessa versione del produttore originale.

in breve, non l'uso di serialversionuid è generalmente la situazione più dannosa.

Quando è necessario supportare la persistenza a lungo termine tramite serializzazione, è quasi sempre necessario utilizzare il codice personalizzato per supportare questo e è necessario impostare esplicitamente serialVersionUID , altrimenti la versione serializzata precedente non sarà deserializzabile con il codice più recente.

Questi scenari richiedono già molta cura al fine di correggere tutti i casi, quando la classe cambia, quindi serialVersionUID è l'ultimo dei tuoi problemi.

Se non ti serve (cioè serializzi e deserializzi sempre con la stessa versione di classe), puoi saltare in sicurezza la dichiarazione esplicita, poiché il valore calcolato si assicurerà che venga utilizzata la versione corretta.

Sia che tu scelga serialVersionUID o meno (ti suggerisco di farlo), dovresti davvero prendere in considerazione la creazione di un set completo di test per la compatibilità seriale.

Vale anche la pena progettare con cura il formato seriale. È effettivamente un'API pubblica.

Se stai solo utilizzando la serializzazione per una chiamata di metodo remota, ad es. chiamare un bean, in cui le classi client e server e jvm sono le stesse, che sospetto sia di gran lunga l'uso più comune, quindi impostare esplicitamente serialVersionUID (come suggerisce ad esempio eclissi) può causare dolore significativo in forma occasionale, bug inspiegabili in cui le istanze di classe incompatibili sono trattate come compatibili a causa del serialVersionUID fisso. Le chiamate remote andranno in silenzio in modo errato durante la serializzazione di basso livello e il problema si ripresenterà in seguito solo quando lo stato dell'oggetto non è coerente. Trovi l'origine del problema solo quando ti rendi conto che le tue classi client e server sono in qualche modo diverse (anche se serialVersionUID non lo è ovviamente). Nella mia esperienza, impostare serialVersionUID per questo motivo fa più male che bene.

Se, d'altra parte, si imposta esplicitamente serialVersionUID per la lettura in vecchi dati, si sta leggendo per definizione in una versione incompatibile e si rischia di finire con un oggetto in uno stato incoerente o incompleto. In questo caso, impostare serialVersionUID è una soluzione alternativa per un problema diverso.

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