IntelliJ IDEA generiert serialVersionUID

297

Wie wird dieser Wert in IntelliJ IDEA generiert?

Ich gehe zu Einstellungen -> Fehler -> Serialisierungsprobleme -> Serialisierbare Klasse ohne 'serialVersionUID', aber die Warnung wird mir immer noch nicht angezeigt. Meine übergeordnete Klasse PKladrBuilding implementiert die Schnittstelle Serializable .

Teil des Codes:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable
Kirill Bazarov
quelle
3
Sind Sie sicher, dass Sie einen Wert generieren müssen, anstatt Ihren eigenen zu definieren? Wenn Sie eine neue Klasse erstellen, würde ich empfehlen, dass Sie z. 1LB. Ihre ID definieren und inkrementieren, wenn sich Ihr serialisiertes Formular ändert. (Siehe stackoverflow.com/questions/888335/… ).
Duncan Jones
1
stackoverflow.com/questions/24573643/… hat eine sehr gute Lösung.
Pankaj Kumar

Antworten:

588

Ich bin nicht sicher, ob Sie eine alte Version von IntelliJ IDEA haben, aber wenn ich zum Menü DateiEinstellungen ...InspektionenSerialisierungsprobleme → Serialisierbare Klasse ohne aktivierte 'serialVersionUID'` gehe, gibt die von Ihnen bereitgestellte Klasse Warnungen aus.

Geben Sie hier die Bildbeschreibung ein

Wenn ich die erste Klasse versuche, sehe ich:

Geben Sie hier die Bildbeschreibung ein

Übrigens: Es wurde mir keine Warnung angezeigt, bis ich { }am Ende jeder Klasse hinzugefügt habe , um den Kompilierungsfehler zu beheben.

Peter Lawrey
quelle
2
Versuchen Sie File| Invalidate CachesWenn dies nicht hilft, wenden Sie sich mit einem Beispielprojekt an [email protected], um es zu reproduzieren.
CrazyCoder
1
Überprüfen Sie idea.log(Hilfe | Anmelden anzeigen ...) auf Ausnahmen. Es ist bekannt, dass das verschlüsselte Home-Verzeichnis unter Linux aufgrund des Kernel-Fehlers Probleme verursacht .
CrazyCoder
1
Ich habe dort viele Ausnahmen .. wie java.lang.NoClassDefFoundError: org / intelligij / lang / annotations / MagicConstant;
Kirill Bazarov
2
Ich habe IDEA neu installiert und Plug-Ins entfernt und es hilft mir. Vielen Dank.
Kirill Bazarov
5
Die Art und Weise, wie ich es in Version 15 zum Laufen gebracht habe, besteht darin, mit der Maus über den Klassennamen zu fahren, um die Warnung zu sehen, und meine Maus langsam in Richtung der Rinne zu bewegen. Zu diesem Zeitpunkt erscheint die "Glühbirne" auf dem Bildschirm. (Versuchen Sie dies einige Male, wenn es beim ersten Mal nicht wie vorgesehen funktioniert). Anschließend können Sie auf die Option Feld erstellen klicken, um die UID zu erstellen. Hoffe, das hilft Leuten, die daran festhalten.
Niyaz
173

Installieren Sie das GenerateSerialVersionUID- Plugin von Olivier Descout.

Gehen Sie zu: Menü DateiEinstellungenPluginsRepositorys durchsuchenGenerateSerialVersionUID

Installieren Sie das Plugin und starten Sie es neu.

Jetzt können Sie die ID aus dem Menü Code → generieren Generieren → serialVersionUID` oder die Verknüpfung generieren .

Sileria
quelle
14
Sollte man wirklich ein externes Plugin benötigen, um dies zum Laufen zu bringen?
H. Rabiee
Ja, Sie benötigen ein Plugin, das bereits Teil des IntelliJ-Plugin-Repositorys ist.
Sileria
Arbeitete für mich an Intellij IDEA 12.1
Sagar Hatekar
Funktioniert für mich am 13.0.2.
user1978019
Funktioniert auf Android Studio 0.8.9
Itai Hanski
67

Ohne Plugins: Sie müssen nur die Hervorhebung in IntelliJ aktivieren:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID'- Flag setzen und klicken 'OK'.

Wenn Ihre Klasse jetzt implementiert wird Serializable, wird eine Hervorhebung angezeigt, und der alt+EnterKlassenname schlägt die Generierung vor private static final long serialVersionUID.

PS: Von hier genommen

Nikhil Katre
quelle
4
Vielen Dank. Ich weiß nicht, warum ich die Glühbirne nicht sehe, aber wenn Sie auf den Klassennamen klicken und Alt-Enter eingeben, reicht dies aus.
John S
2
Antwort wird von hier
Serhii Maksymchuk
Dies ist aktueller
Christian Matthew
39

Nachdem ich einige Zeit mit Serialisierung verbracht habe, finde ich, dass wir nicht serialVersionUIDmit einem zufälligen Wert generieren sollten, sondern ihm einen aussagekräftigen Wert geben sollten.

Hier ist ein Detailkommentar dazu. Ich bewältige den Kommentar hier.

Eigentlich sollten Sie keine UIDs der seriellen Version "generieren". Es ist eine dumme "Funktion", die sich aus dem allgemeinen Missverständnis darüber ergibt, wie diese ID von Java verwendet wird. Sie sollten diesen IDs aussagekräftige, lesbare Werte geben, z. B. beginnend mit 1L, und sie jedes Mal erhöhen, wenn Sie der Meinung sind, dass die neue Version der Klasse alle vorherigen Versionen (die möglicherweise zuvor serialisiert wurden) überflüssig machen sollte. Alle Dienstprogramme, die solche IDs generieren, tun im Grunde das, was die JVM tut, wenn die ID nicht definiert ist: Sie generieren den Wert basierend auf dem Inhalt der Klassendatei und liefern daher unlesbare bedeutungslose lange Ganzzahlen. Wenn Sie möchten, dass jede Version Ihrer Klasse unterschiedlich ist (in den Augen der JVM), sollten Sie nicht einmal den Wert für serialVersionUID angeben, da die JVM im laufenden Betrieb einen Wert erzeugt. und der Wert jeder Version Ihrer Klasse ist eindeutig. Der Zweck der expliziten Definition dieses Werts besteht darin, den Serialisierungsmechanismus anzuweisen, verschiedene Versionen der Klasse mit derselben SVUID so zu behandeln, als wären sie gleich, z. B. die älteren serialisierten Versionen nicht abzulehnen. Wenn Sie also die ID definieren und niemals ändern (und ich gehe davon aus, dass Sie dies tun, da Sie sich auf die automatische Generierung verlassen und Ihre IDs wahrscheinlich nie neu generieren), stellen Sie sicher, dass alle - auch absolut unterschiedlichen - Versionen von Ihre Klasse wird vom Serialisierungsmechanismus als gleich angesehen. Ist es das was du willst? Wenn nicht, und wenn Sie tatsächlich die Kontrolle darüber haben möchten, wie Ihre Objekte erkannt werden, sollten Sie einfache Werte verwenden, die Sie selbst verstehen und leicht aktualisieren können, wenn Sie feststellen, dass sich die Klasse erheblich geändert hat.

Hoffe das hilft. Viel Glück.

Emdadul Sawon
quelle
2
Danke, ich habe diese einfache Tatsache so lange übersprungen!
Dedek
1
Ich würde das tatsächlich serialVersionUIDmit einer neuen Zufallszahl neu generieren, wenn ich alte Versionen bei der Deserialisierung nicht unterstützen möchte. Vielleicht muss ich keine Zufallszahlen verwenden, sondern kann mit 1 beginnen und diese erhöhen. Allerdings hat 3Ldas für mich dann keine größere Bedeutung -3518231192373568183L. Daher denke ich, dass beide Lösungen ähnlich funktionieren. Die Zufallszahl könnte jedoch den Vorteil haben, dass sie auf nichtlinearen Historien mit Gabeln und Zweigen funktioniert.
JojOatXGME
16

Um den Wert zu generieren, verwenden Sie

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

und geben Sie der randomLong-Vorlagenvariablen den folgenden Wert: groovyScript ("new Random (). nextLong (). abs ()")

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

Pharsfalvi
quelle
1
Ich liebe diesen Kommentar. Mit Live-Vorlagen ist dies mit Sicherheit die schnellste und anpassbarste Lösung (ich habe zum Beispiel die Newline entfernt). Zum Konfigurieren gehen Sie zu Android Studio> Einstellungen> Editor> Live-Vorlagen und erstellen Sie dort eine neue (Plus-Symbol) mit diesem Wert und verwenden Sie Bearbeitungsvariablen, um das Skript
einzugeben
13

Außerdem können Sie eine Live-Vorlage hinzufügen, die die Arbeit erledigt.

Drücken Sie dazu Ctrl+Alt+S-> "Live Templates"Abschnitt -> other(oder w / w Sie wünschen)

Und dann erstellen Sie eine neue mit einer Definition wie dieser:

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

Wählen Sie dann den definitionBereich aus und speichern Sie ihn unter'serial'

Jetzt können Sie den serialTABKlassenkörper eingeben.

fallens4e
quelle
3

Eine andere Möglichkeit, die serialVersionUID zu generieren, besteht darin, sie >Analyze >Run Inspection by Nameüber das Kontextmenü (oder die Tastenkombination, die standardmäßig ctrl+ alt+ shift+ iist) zu verwenden und dann "Serializable class without 'serialVersionUID'" einzugeben (oder einfach "serialVersionUID" und den vorausgehenden Typ einzugeben Funktion wird es für Sie finden.

Idee> Analysieren> Inspektion nach Namen ausführen Sie erhalten dann ein Kontextmenü, in dem Sie auswählen können, wo die Inspektionen ausgeführt werden sollen (z. B. alle aus einem bestimmten Modul, einem gesamten Projekt, einer Datei, ...).

Bei diesem Ansatz müssen Sie nicht einmal die allgemeinen Inspektionsregeln auf irgendetwas festlegen.

Alexander
quelle
Schön, das hat den Job für mich gemacht. Es fand die fehlende Variable und bot die Möglichkeit, sie hinzuzufügen.
Arenaq
@arenaq froh, das hat jemand anderem geholfen ;-)
Alexander
2

Mit Version v2018.2.1

Gehe zu

Einstellungen> Editor> Inspektionen> Java> Serialisierungsprobleme> Aktivieren Sie "Serialisierbare Klasse ohne 'serialVersionUID'".

Neben der Klassendeklaration sollte eine Warnung angezeigt werden.

YLyu
quelle
1

Ich verwende Android Studio 2.1 und habe eine bessere Konsistenz beim Erhalten der Glühbirne, indem ich auf den Klassennamen klicke und für eine Sekunde darüber schwebe.

Johnny Wu
quelle
1

Fügen Sie der anderen Gruppe eine Live-Vorlage mit dem Namen "ser" hinzu, setzen Sie sie auf "Anwendbar in Java: Deklaration" und deaktivieren Sie "FQ-Namen verkürzen". Geben Sie ihm einen Vorlagentext von nur:

$serial$

Bearbeiten Sie nun die Variablen und setzen Sie die Seriennummer auf:

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())

Es wird das Standard-Gradle-Projektlayout angenommen. Ändere / baue / zu / Ziel / für Maven.

Greg Allen
quelle
1

Einfachste moderne Methode: Alt+ Enteran

private static final long serialVersionUID = ;

IntelliJ unterstreicht den Raum nach dem =. Setzen Sie den Cursor darauf und drücken Sie alt+ Enter( Option+ Enterauf dem Mac). Sie erhalten ein Popover mit der Aufschrift "Randomly Change serialVersionUID Initializer". Drücken Sie einfach die Eingabetaste, und dieser Bereich wird mit einer zufälligen Länge gefüllt.

jeremysprofile
quelle
0

Wenn Sie die fehlende serialVersionUID für eine Reihe von Dateien hinzufügen möchten, funktioniert IntelliJ IDEA möglicherweise nicht sehr gut. Ich überlege mir ein einfaches Skript, um dieses Ziel mit Leichtigkeit zu erreichen:

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

Sie speichern dieses Skript beispielsweise add_serialVersionUID.shin Ihrem ~/binOrdner. Anschließend führen Sie es im Stammverzeichnis Ihres Maven- oder Gradle-Projekts wie folgt aus:

add_serialVersionUID.sh < myJavaToAmend.lst

Diese .lst enthält die Liste der Java-Dateien zum Hinzufügen der serialVersionUID im folgenden Format:

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

Dieses Skript verwendet das JDK serialVer-Tool. Es ist ideal für Situationen, in denen Sie eine große Anzahl von Klassen ändern möchten, für die zunächst keine serialVersionUID festgelegt wurde, während die Kompatibilität mit den alten Klassen erhalten bleibt.

schnell18
quelle