Domanda

In Java, i campi statici e transitori non sono serializzati.Tuttavia, ho scoperto che l'inizializzazione dei campi statici provoca la modifica del serialVersionUID generato.Per esempio, static int MYINT = 3; fa sì che serialVersionUID cambi.In questo esempio ha senso perché versioni diverse della classe otterrebbero valori iniziali diversi.Perché qualsiasi inizializzazione modifica il serialVersionUID?Per esempio, static String MYSTRING = System.getProperty("foo"); provoca anche la modifica di serialVersionUID.

Per essere precisi, la mia domanda è: perché l'inizializzazione con un metodo causa la modifica di serialVersionUID.Il problema che ho riscontrato è che ho aggiunto un nuovo campo statico inizializzato con un valore di proprietà di sistema (getProperty).Questa modifica ha causato un'eccezione di serializzazione su una chiamata remota.

È stato utile?

Soluzione

Puoi trovare alcune informazioni a riguardo nel errore 4365406 e nel algoritmo per il calcolo serialVersionUID.Fondamentalmente, quando si modifica l'inizializzazione del proprio file static membro con System.getProperty(), il compilatore introduce un nuovo file static proprietà nella tua classe che fa riferimento a System class (presumo che il System la classe non era precedentemente referenziata nella classe) e poiché questa proprietà introdotta dal compilatore non è privata, prende parte alla serialVersionUID calcolo.

Moralità:usare sempre esplicito serialVersionUID, risparmierai alcuni cicli della CPU e qualche grattacapo :)

Altri suggerimenti

Il serialVersionUID automatico viene calcolato in base ai membri di una classe.Questi possono essere visualizzati per un file di classe utilizzando lo strumento javap in Sun JDK.

Nel caso menzionato nella domanda, il membro che viene aggiunto/rimosso è l'inizializzatore statico.Questo appare come ()V nei file di classe.Il contenuto del metodo può essere disassemblato utilizzando javap -c.Dovresti essere in grado di distinguere la chiamata System.getProperty("foo") e l'assegnazione a MYSTRING.Tuttavia un'assegnazione con una stringa letterale (o qualsiasi costante in fase di compilazione come definito dalla specifica del linguaggio Java) è supportata direttamente dal file di classe, eliminando così la necessità di un inizializzatore statico.

Un caso comune per il codice destinato a J2SE 1.4 (usa -source 1.4 -target 1.4) o versioni precedenti sono i campi statici su vecchie istanze di classe che appaiono come valori letterali di classe nel codice sorgente (MyClass.class).L'istanza Class viene cercata su richiesta con Class.forName e archiviata in un campo statico.È questo campo statico che interrompe serialVersionUID.Da J2SE 5.0, una variante del codice operativo ldc fornisce il supporto diretto per i valori letterali di classe, eliminando la necessità del campo sintetico.Ancora una volta, tutto questo può essere mostrato con javap -c.

Se ho letto correttamente le specifiche, l'automatic serialVersionUID non dovrebbe cambiare se si modifica il valore di un campo statico o transitorio.Dare un'occhiata a Capitolo 5.6 della spec.

Tuttavia, se ci pensi un po', inizi serializzando un oggetto che ha static int MYINT = 3, quando poi deserializzi la classe ti aspetti di riavere lo stesso oggetto, cioè con MYINT = 3.Quindi, se modifichi l'inizializzazione statica ti aspetteresti il ​​file serialVersionUID cambiare perché non è possibile ottenere nuovamente lo stesso oggetto.

Comunque, mantienilo in tutte le tue classi serializzabili e puoi controllare il file serialVersionUID:

private static final long serialVersionUID = 7526472295622776147L;

Ho aggiornato la domanda per essere più chiara.Capisco perché l'inizializzazione con un valore letterale cambia il file serialVersionUID ma non perché l'inizializzazione dinamica lo cambia.Se inizializzi con un metodo, il valore, ovviamente, potrebbe essere sempre diverso.

Impostazione del serialVersionUID esplicitamente va bene in una versione successiva della classe solo se si è sicuri che si tratti di una modifica sicura.

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