IntelliJ IDEA che genera serialVersionUID


297

Come si genera questo valore in IntelliJ IDEA?

Vado in Impostazioni -> Errori -> Problemi di serializzazione -> Classe serializzabile senza 'serialVersionUID', ma ancora non mi mostra l'avviso. Il mio genitore PKladrBuilding implementa l' interfaccia Serializable .

Parte del codice:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable

3
Sei sicuro di dover generare un valore, piuttosto che definire il tuo? Se stai creando una nuova classe, ti consiglio di definire, ad esempio, 1Lcome ID e incremento quando il modulo serializzato cambia. (Vedi stackoverflow.com/questions/888335/… ).
Duncan Jones,

Risposte:


588

Non sono sicuro che tu abbia una vecchia versione di IntelliJ IDEA, ma se vado al menu FileImpostazioni ... IspezioniProblemi di serializzazione → Classe serializzabile senza 'serialVersionUID' `abilitato, la classe che fornisci mi dà avvertimenti.

Inserisci qui la descrizione dell'immagine

Se provo la prima classe vedo:

Inserisci qui la descrizione dell'immagine

BTW: Non mi ha mostrato un avviso fino a quando non ho aggiunto { }alla fine di ogni classe per correggere l'errore di compilazione.


2
Prova File| Invalidate Caches, se non aiuta, contatta support@jetbrains.com con un progetto di esempio da riprodurre.
CrazyCoder,

1
Controllare idea.log(Aiuto | Rivela Accedi ...) per le eccezioni, è noto che la directory home crittografata su Linux causa problemi a causa del bug del kernel .
CrazyCoder,

1
ho molte eccezioni lì .. come java.lang.NoClassDefFoundError: org / intellij / lang / annotations / MagicConstant;
Kirill Bazarov,

2
Ho reinstallato IDEA e rimosso i plug-in e questo mi aiuta. Grazie mille.
Kirill Bazarov,

5
Il modo in cui l'ho fatto funzionare nella v15 è passare sopra il ClassName per vedere l'avvertimento e spostare lentamente il mouse verso la grondaia. A quel punto la "lampadina" appare sullo schermo. (Provalo alcune volte se non funziona come previsto la prima volta). Quindi puoi fare clic sull'opzione Crea campo per creare l'UID. Spero che questo aiuti le persone che sono bloccate su questo.
Niyaz,

173

Installa GenerateSerialVersionUID plug-in di Olivier Descout.

Vai a: menu FileImpostazioniPluginSfoglia repositoryGenerateSerialVersionUID

Installa il plug-in e riavvia.

Ora puoi generare l'id dal menu CodiceGenera → serialVersionUID` o il collegamento.


14
Uno dovrebbe richiedere davvero un plugin esterno per farlo funzionare?
H.Rabiee,

Sì, è necessario un plug-in che fa già parte del repository di plug-in IntelliJ.
Sileria,

Ha lavorato per me su Intellij IDEA 12.1
Sagar Hatekar il

Funziona per me il 13.0.2.
user1978019

Funziona su Android Studio 0.8.9
Itai Hanski,

67

Senza plugin: devi solo abilitare l'evidenziazione in IntelliJ:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID'- imposta flag e fai clic 'OK'.

Ora, se la tua classe viene implementata Serializable, vedrai l'evidenziazione e alt+Enteril nome della classe proporrà di generare private static final long serialVersionUID.

PS: preso da qui


4
Grazie. Non so perché non vedo la lampadina, ma facendo clic sul nome della classe e digitando Alt-Enter fa il trucco.
John S,

2
La risposta viene rubata da qui
Serhii Maksymchuk,

questo è più aggiornato
Christian Matthew l'

39

Dopo aver trascorso un po 'di tempo sulla serializzazione, trovo che non dovremmo generare serialVersionUID con un valore casuale, dovremmo dargli un valore significativo.

Ecco un commento dettagliato su questo. Sto affrontando il commento qui.

In realtà, non dovresti "generare" UID di versione seriale. È una stupida "caratteristica" che deriva dall'incomprensione generale di come tale ID viene utilizzato da Java. Dovresti fornire a questi ID valori significativi e leggibili, ad esempio iniziando con 1L e incrementandoli ogni volta che ritieni che la nuova versione della classe debba rendere obsolete tutte le versioni precedenti (che potrebbero essere precedentemente serializzate). Tutte le utility che generano tali ID fanno sostanzialmente quello che fa la JVM quando l'ID non è definito: generano il valore in base al contenuto del file di classe, ottenendo quindi numeri interi lunghi senza significato illeggibili. Se desideri che ogni singola versione della tua classe sia distinta (agli occhi della JVM), non dovresti nemmeno specificare il valore serialVersionUID dopo che la JVM ne produrrà una al volo, e il valore di ogni versione della tua classe sarà unico. Lo scopo di definire esplicitamente quel valore è di dire al meccanismo di serializzazione di trattare diverse versioni della classe che hanno lo stesso SVUID come se fossero uguali, ad esempio non rifiutare le versioni serializzate precedenti. Quindi, se definisci l'ID e non lo cambi mai (e presumo sia quello che fai dal momento che fai affidamento sulla generazione automatica e probabilmente non rigenererai mai i tuoi ID) stai assicurando che tutte le versioni - anche assolutamente diverse - di la tua classe sarà considerata la stessa dal meccanismo di serializzazione. È questo che vuoi? In caso contrario, e se vuoi davvero avere il controllo su come vengono riconosciuti i tuoi oggetti, dovresti utilizzare valori semplici che puoi capire e aggiornare facilmente quando decidi che la classe è cambiata in modo significativo.

Spero che questo ti aiuti. In bocca al lupo.


2
Grazie, ho saltato questo semplice fatto per così tanto tempo!
Dedek,

1
In realtà vorrei rigenerare il serialVersionUIDcon un nuovo numero casuale quando non voglio supportare le vecchie versioni sulla deserializzazione. Forse non ho bisogno di usare numeri casuali, ma posso iniziare con 1 e aumentarlo. Tuttavia, 3Lnon ha più significato per me allora -3518231192373568183L. Pertanto, immagino che entrambe le soluzioni funzionino in modo simile. Tuttavia, il numero casuale potrebbe avere il vantaggio di svegliarsi su storie non lineari con forchette e rami.
JojOatXGME,

16

Per generare il valore utilizzare

private static final long serialVersionUID = $randomLong$L;
$END$

e fornire alla variabile modello randomLong il seguente valore: groovyScript ("new Random (). nextLong (). abs ()")

https://pharsfalvi.wordpress.com/2015/03/18/adding-serialversionuid-in-idea/


1
Adoro questo commento, usando modelli live questa è sicuramente la soluzione più veloce e più personalizzabile (ho rimosso la nuova riga per esempio). Per configurare vai su Android Studio> Preferenze> Editor> Modelli live e creane uno nuovo lì (icona più) con questo valore e usa le variabili di modifica per inserire lo script
hcpl

13

Inoltre puoi aggiungere un modello live che farà il lavoro.

Per farlo premi Ctrl+Alt+S-> "Live Templates"sezione -> other(o w / e che desideri)

E quindi crearne uno nuovo con una definizione come questa:

private static final long serialVersionUID = 1L;
$END$

Quindi selezionare l' definitionambito e salvarlo come'serial'

Ora puoi digitare il serialTABcorpo della classe.


3

Un altro modo per generare serialVersionUID è utilizzare >Analyze >Run Inspection by Namedal menu di scelta rapida (o la scorciatoia da tastiera, che è ctrl+ alt+ shift+ iper impostazione predefinita) e quindi digitare "Classe serializzabile senza" serialVersionUID "" (o semplicemente digitare "serialVersionUID" e il tipo avanti la funzione lo troverà per te.

Idea> Analizza> Esegui ispezione per nome Verrà quindi visualizzato un menu di scelta rapida in cui è possibile scegliere dove eseguire le ispezioni (ad esempio, tutto da un modulo specifico, un intero progetto, un file, ...)

Con questo approccio non è nemmeno necessario impostare le regole generali di ispezione su nulla.


Bello, questo ha fatto il lavoro per me. Ha trovato la variabile mancante e ha presentato l'opzione per aggiungerla.
arenaq,

@arenaq felice, questo ha aiutato qualcun altro ;-)
Alexander

2

Con la versione v2018.2.1

Vai a

Preferenze> Editor> Ispezioni> Java> Problemi di serializzazione> attiva "Classe serializzabile senza 'serialVersionUID'".

Un avviso dovrebbe apparire accanto alla dichiarazione di classe.


1

Sto usando Android Studio 2.1 e ho una maggiore coerenza nell'ottenere la lampadina facendo clic sul nome della classe e passandoci sopra per un secondo.


1

Aggiungi un modello live chiamato "ser" all'altro gruppo, impostalo su "Applicabile in Java: dichiarazione" e deseleziona "Abbrevia nomi FQ". Dagli un testo modello di solo:

$serial$

Ora modifica le variabili e imposta seriale su:

groovyScript("(System.env.JDK_HOME+'/bin/serialver -classpath '+com.intellij.openapi.fileEditor.FileDocumentManager.instance.getFile(_editor.document).path.replaceAll('/java/.*','').replaceAll('/src/','/build/classes/')+' '+_1).execute().text.replaceAll('.*: *','')",qualifiedClassName())

Presuppone il layout standard del progetto Gradle. Cambia / build / in / target / per Maven.


1

Metodo moderno più semplice: Alt+ Enterattivo

private static final long serialVersionUID = ;

IntelliJ sottolineerà lo spazio dopo il =. posiziona il cursore su di esso e premi alt+ Enter( Option+ Entersu Mac). Otterrai un popover che dice "Cambia casualmente serialVersionUID Initializer". Basta premere invio e popolerà quello spazio con una lunghezza casuale.


0

Se si desidera aggiungere il serialVersionUID assente per un mucchio di file, IntelliJ IDEA potrebbe non funzionare molto bene. Vengo a una semplice sceneggiatura per raggiungere questo obiettivo con facilità:

base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes

while read f
do
    clazz=${f//\//.}
    clazz=${clazz/%.java/}
    seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
    perl -ni.bak -e "print $_; printf qq{%s\n}, q{    private $seruidstr} if /public class/" $src_dir/$f
done

Salvate questo script, dite come add_serialVersionUID.shnella vostra ~/bincartella. Quindi lo esegui nella directory principale del tuo progetto Maven o Gradle come:

add_serialVersionUID.sh < myJavaToAmend.lst

Questo .lst include l'elenco di file Java per aggiungere serialVersionUID nel seguente formato:

com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java

Questo script utilizza lo strumento JVK serialVer. È ideale per una situazione in cui si desidera modificare un numero enorme di classi che non hanno impostato serialVersionUID in primo luogo mantenendo la compatibilità con le vecchie classi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.