IntelliJ IDEA generuje serialVersionUID


297

Jak wygenerować tę wartość w IntelliJ IDEA?

Idę do Ustawienia -> Błędy -> Problemy z serializacją -> Klasa możliwa do serializacji bez „serialVersionUID”, ale nadal nie wyświetla mi ostrzeżenia. Mój rodzic PKladrBuilding rodzic implementuje interfejs Serializable .

Część kodu:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable

3
Czy na pewno musisz wygenerować wartość zamiast definiować własną? Jeśli tworzysz nową klasę, zaleciłbym zdefiniowanie np. 1LJako swojego identyfikatora i przyrostu, gdy zmieni się formularz zserializowany. (Zobacz stackoverflow.com/questions/888335/… ).
Duncan Jones

Odpowiedzi:


588

Nie jestem pewien, czy masz starą wersję IntelliJ IDEA, ale jeśli przejdę do menu PlikUstawienia ...InspekcjeProblemy z serializacją → Klasa możliwa do serializacji bez włączonej opcji „serialVersionUID”, klasa, którą podajesz, daje mi ostrzeżenia.

Wpisz opis zdjęcia tutaj

Jeśli spróbuję pierwszej klasy, zobaczę:

Wpisz opis zdjęcia tutaj

BTW: Nie pokazało mi ostrzeżenia, dopóki nie dodałem { }na końcu każdej klasy, aby naprawić błąd kompilacji.


2
Spróbuj File| Invalidate Caches, jeśli to nie pomoże, skontaktuj się z support@jetbrains.com z przykładowym projektem do odtworzenia.
CrazyCoder,

1
Sprawdź idea.log(Pomoc | Reveal Log in ...) wyjątki, wiadomo, że zaszyfrowany katalog domowy w systemie Linux powoduje problemy z powodu błędu jądra .
CrazyCoder,

1
Mam tam wiele wyjątków .. jak java.lang.NoClassDefFoundError: org / intellij / lang / annotations / MagicConstant;
Kirill Bazarov

2
Ponownie zainstalowałem IDEA i usunąłem wtyczki i to mi pomaga. Wielkie dzięki.
Kirill Bazarov

5
Sposób, w jaki działałem w wersji 15, to najechanie kursorem na nazwę klasy, aby zobaczyć ostrzeżenie i powoli przesunąć mysz w kierunku rynny. W tym momencie na ekranie pojawia się „żarówka”. (Spróbuj to kilka razy, jeśli za pierwszym razem nie działa zgodnie z przeznaczeniem). Następnie możesz kliknąć opcję tworzenia pola, aby utworzyć identyfikator użytkownika. Mam nadzieję, że to pomaga ludziom, którzy utknęli w tym.
Niyaz

173

Zainstaluj wtyczkę GenerateSerialVersionUID autorstwa Oliviera Descouta.

Przejdź do: menu PlikUstawieniaWtyczkiPrzeglądaj repozytoriaGenerateSerialVersionUID

Zainstaluj wtyczkę i uruchom ponownie.

Teraz możesz wygenerować identyfikator z menu KodGeneruj → serialVersionUID` lub skrót.


14
Czy naprawdę potrzebna jest zewnętrzna wtyczka, aby to działało?
H.Rabiee

Tak, potrzebujesz wtyczki, która jest już częścią repozytorium wtyczek IntelliJ.
Sileria

Pracowałem dla mnie nad Intellij IDEA 12.1
Sagar Hatekar

Działa dla mnie w 13.0.2.
user1978019

Działa na Androidzie Studio 0.8.9
Itai Hanski

67

Bez żadnych wtyczek: wystarczy włączyć wyróżnienie w IntelliJ:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID'- ustaw flagę i kliknij 'OK'.

Teraz, jeśli twoja klasa zaimplementuje Serializable, zobaczysz wyróżnienie, a alt+Enterna nazwie klasy zaproponuje wygenerowanie private static final long serialVersionUID.

PS: Zaczerpnięte stąd


4
Dzięki. Nie wiem, dlaczego nie widzę żarówki, ale kliknięcie nazwy klasy i wpisanie Alt-Enter rozwiązuje problem.
John S,

2
Odpowiedź została skradziona stąd
Serhii Maksymchuk

to jest bardziej aktualne
Christian Matthew

39

Po spędzeniu czasu na serializacji uważam, że nie powinniśmy generować serialVersionUID losowych wartości, powinniśmy nadać im znaczącą wartość.

Oto komentarz do szczegółów na ten temat. Skopiuję komentarz tutaj.

W rzeczywistości nie powinieneś „generować” identyfikatorów UID w wersji szeregowej. Jest to głupia „funkcja”, która wynika z ogólnego niezrozumienia sposobu używania tego identyfikatora przez Javę. Powinieneś nadać tym identyfikatorom znaczące, czytelne wartości, np. Zaczynając od 1L, i zwiększać je za każdym razem, gdy myślisz, że nowa wersja klasy powinna sprawić, że wszystkie poprzednie wersje (które mogły być wcześniej serializowane) stały się nieaktualne. Wszystkie narzędzia, które generują takie identyfikatory, w zasadzie robią to, co robi JVM, gdy identyfikator nie jest zdefiniowany: generują wartość na podstawie zawartości pliku klasy, stąd powstają nieczytelne długie liczby całkowite bez znaczenia. Jeśli chcesz, aby każda wersja twojej klasy była odrębna (w oczach JVM), nie powinieneś nawet określać wartości serialVersionUID, ponieważ JVM będzie produkować ją w locie, a wartość każdej wersji twojej klasy będzie niepowtarzalna. Celem jawnego zdefiniowania tej wartości jest poinformowanie mechanizmu serializacji, aby traktował różne wersje klasy, które mają ten sam SVUID, jakby były takie same, np. Aby nie odrzucał starszych wersji serializowanych. Jeśli więc zdefiniujesz identyfikator i nigdy go nie zmienisz (i zakładam, że tak właśnie postępujesz, ponieważ polegasz na automatycznym generowaniu i prawdopodobnie nigdy nie generujesz ponownie swoich identyfikatorów), zapewniasz, że wszystkie - nawet absolutnie różne - wersje twoja klasa będzie traktowana tak samo przez mechanizm serializacji. Czy tego chcesz? Jeśli nie, i jeśli naprawdę chcesz mieć kontrolę nad sposobem rozpoznawania obiektów, powinieneś używać prostych wartości, które sam możesz zrozumieć i łatwo zaktualizować, gdy zdecydujesz, że klasa znacząco się zmieniła.

Mam nadzieję że to pomoże. Powodzenia.


2
Dzięki, tak długo pomijałem ten prosty fakt!
dedek,

1
Naprawdę wygenerowałbym ponownie serialVersionUIDz nową losową liczbą, gdy nie chcę obsługiwać starych wersji przy deserializacji. Może nie muszę używać liczb losowych, ale mogę zacząć od 1 i zwiększyć go. Nie 3Lma to jednak dla mnie większego znaczenia -3518231192373568183L. Dlatego wydaje mi się, że oba rozwiązania działają podobnie. Jednak liczba losowa może mieć tę zaletę, że budzi się w nieliniowych historiach z widelcami i rozgałęzieniami.
JojOatXGME

16

Aby wygenerować wartość, użyj

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

i podaj zmienną szablonu randomLong o następującej wartości: groovyScript („new Random (). nextLong (). abs ()”)

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


1
uwielbiam ten komentarz, używając szablonów na żywo jest to z pewnością najszybsze rozwiązanie i najbardziej konfigurowalne (na przykład usunąłem nowy wiersz). Aby skonfigurować, przejdź do Android Studio> Preferencje> Edytor> Szablony na żywo i utwórz tam nową (z ikoną) o tej wartości i użyj zmiennych edycji, aby wprowadzić skrypt
hcpl

13

Ponadto możesz dodać szablon na żywo, który wykona pracę.

Aby to zrobić, naciśnij Ctrl+Alt+S-> "Live Templates"sekcja -> other(lub w / e chcesz)

A następnie utwórz nową z taką definicją:

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

Następnie wybierz definitionzakres i zapisz go jako'serial'

Teraz możesz wpisać serialTABtreść klasy.


3

Innym sposobem na wygenerowanie serialVersionUID jest użycie >Analyze >Run Inspection by Namez menu kontekstowego (lub skrótu klawiaturowego, który domyślnie jest ctrl+ alt+ shift+ i), a następnie wpisz „Serializable class bez„ serialVersionUID ”” (lub po prostu wpisz „serialVersionUID” i typ naprzód funkcja znajdzie to dla ciebie.

Pomysł> Analiza> Uruchom inspekcję według nazwy Otrzymasz wtedy menu kontekstowe, w którym możesz wybrać, gdzie przeprowadzać inspekcje (np. Wszystkie z określonego modułu, całego projektu, jednego pliku, ...)

Dzięki takiemu podejściu nie musisz nawet ustawiać ogólnych zasad inspekcji na niczym.


Fajnie, to zadziałało dla mnie. Znalazł brakującą zmienną i przedstawił opcję jej dodania.
arenaq

@arenaq cieszę się, że pomogło to komuś innemu ;-)
Alexander

2

Z wersją v2018.2.1

Iść do

Preferencje> Edytor> Inspekcje> Java> Problemy z serializacją> przełącz „Serializowalną klasę bez„ serialVersionUID ””.

Ostrzeżenie powinno pojawić się obok deklaracji klasy.


1

Korzystam z Androida Studio 2.1 i mam większą spójność w uzyskiwaniu żarówki, klikając nazwę klasy i najeżdżając na nią myszą przez sekundę.


1

Dodaj szablon aktywny o nazwie „ser” do drugiej grupy, ustaw go na „Dotyczy w Javie: deklaracja” i odznacz „Skróć nazwy FQ”. Daj mu tekst szablonu:

$serial$

Teraz edytuj zmienne i ustaw serial na:

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

Zakłada standardowy układ projektu Gradle. Zmień / build / to / target / for Maven.


1

Najłatwiejsza nowoczesna metoda: Alt+ Enterwłączony

private static final long serialVersionUID = ;

IntelliJ podkreśli przestrzeń po =. umieść na nim kursor i naciśnij alt+ Enter( Option+ Enterna Macu). Pojawi się okienko z napisem „Losowo zmień inicjator serialVersionUID”. Po prostu wciśnij Enter, a zapełni to miejsce losową długością.


0

Jeśli chcesz dodać nieobecny serialVersionUID dla kilku plików, IntelliJ IDEA może nie działać zbyt dobrze. Wymyślam prosty skrypt, aby z łatwością osiągnąć ten cel:

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

Zapisujesz ten skrypt, powiedz jak add_serialVersionUID.shw ~/binfolderze. Następnie uruchom go w katalogu głównym projektu Maven lub Gradle, np .:

add_serialVersionUID.sh < myJavaToAmend.lst

Ten plik .lst zawiera listę plików Java do dodania serialVersionUID w następującym formacie:

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

Ten skrypt używa narzędzia JDK serialVer. Jest to idealne rozwiązanie w sytuacji, gdy chcesz zmienić ogromną liczbę klas, które w pierwszej kolejności nie miały ustawionego serialVersionUID, zachowując zgodność ze starymi klasami.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.