IntelliJ IDEA menghasilkan serialVersionUID

297

Bagaimana cara menghasilkan nilai ini di IntelliJ IDEA?

Saya pergi ke Pengaturan -> Kesalahan -> Masalah serialisasi -> Kelas serializable tanpa 'serialVersionUID', tetapi masih tidak menunjukkan peringatan kepada saya. Induk PKladrBuilding kelas saya mengimplementasikan antarmuka Serializable .

Bagian dari kode:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable
Kirill Bazarov
sumber
3
Apakah Anda yakin harus menghasilkan nilai, alih-alih menentukan nilai Anda sendiri? Jika Anda membuat kelas baru, saya akan merekomendasikan Anda mendefinisikan misalnya 1Lsebagai ID Anda dan kenaikan ketika bentuk serial Anda berubah. (Lihat stackoverflow.com/questions/888335/… ).
Duncan Jones
1
stackoverflow.com/questions/24573643/… memiliki solusi yang sangat bagus.
Pankaj Kumar

Jawaban:

588

Saya tidak yakin apakah Anda memiliki IntelliJ IDEA versi lama, tetapi jika saya masuk ke menu FileSettings ...InspeksiMasalah serialisasi → Kelas serial tanpa mengaktifkan 'serialVersionUID'`, kelas yang Anda berikan memberi saya peringatan.

Masukkan deskripsi gambar di sini

Jika saya mencoba kelas pertama, saya melihat:

Masukkan deskripsi gambar di sini

BTW: Itu tidak menunjukkan saya peringatan sampai saya menambahkan { }ke akhir setiap kelas untuk memperbaiki kesalahan kompilasi

Peter Lawrey
sumber
2
Coba File| Invalidate Caches, jika tidak membantu, hubungi [email protected] dengan proyek sampel untuk direproduksi.
CrazyCoder
1
Periksa idea.log(Help | Reveal Log in ...) untuk pengecualian, direktori home terenkripsi di Linux diketahui menyebabkan masalah karena bug kernel .
CrazyCoder
1
saya punya banyak pengecualian di sana .. seperti java.lang.NoClassDefFoundError: org / intellij / lang / annotations / MagicConstant;
Kirill Bazarov
2
Saya telah menginstal ulang IDEA dan menghapus plug-in dan itu membantu saya. Tnx banyak.
Kirill Bazarov
5
Cara saya membuatnya bekerja di v15 adalah melayang di atas ClassName untuk melihat peringatan dan gerakkan mouse saya perlahan ke selokan. Pada saat itu "bola lampu" muncul di layar. (Coba ini beberapa kali jika tidak berfungsi seperti yang dimaksudkan pertama kali). Kemudian Anda dapat mengklik opsi buat bidang untuk membuat uid. Semoga ini bisa membantu orang yang terjebak dalam hal ini.
Niyaz
173

Instal GenerateSerialVersionUID plugin oleh Olivier Descout.

Buka: menu FilePengaturanPluginsJelajahi repositoriGenerateSerialVersionUID

Instal plugin dan mulai kembali.

Sekarang Anda dapat membuat id dari menu CodeGenerate → serialVersionUID` atau pintasan.

Sileria
sumber
14
Haruskah seseorang benar-benar membutuhkan plugin eksternal agar ini berfungsi?
H.Rabiee
Ya, Anda memerlukan plugin yang sudah menjadi bagian dari gudang plugin IntelliJ.
Sileria
Bekerja untuk saya di Intellij IDEA 12.1
Sagar Hatekar
Bekerja untuk saya di 13.0.2.
user1978019
Bekerja di Android Studio 0.8.9
Itai Hanski
67

Tanpa plugin: Anda hanya perlu mengaktifkan highlight di IntelliJ:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID' - atur bendera dan klik 'OK' .

Sekarang, jika kelas Anda mengimplementasikan Serializable, Anda akan melihat highlight, dan alt+Enternama kelas akan mengusulkan untuk menghasilkanprivate static final long serialVersionUID .

PS: Diambil dari sini

Nikhil Katre
sumber
4
Terima kasih. Saya tidak tahu mengapa saya tidak melihat bola lampu, tetapi mengklik nama kelas dan mengetik Alt-Enter melakukan triknya.
John S
2
Jawaban dicuri dari sini
Serhii Maksymchuk
ini lebih mutakhir
Christian Matthew
39

Setelah menghabiskan beberapa waktu pada Serialisasi, saya menemukan bahwa, kita tidak boleh menghasilkan serialVersionUIDdengan beberapa nilai acak, kita harus memberikannya nilai yang berarti.

Berikut adalah komentar detail tentang ini. Saya mengatasi komentar di sini.

Sebenarnya, Anda seharusnya tidak "menghasilkan" UID versi serial. Ini adalah "fitur" bodoh yang berasal dari kesalahpahaman umum tentang bagaimana ID itu digunakan oleh Java. Anda harus memberikan ID ini nilai-nilai yang bermakna dan dapat dibaca, misalnya mulai dengan 1L, dan menambahkannya setiap kali Anda berpikir versi baru kelas harus membuat semua versi sebelumnya (yang mungkin serial) tidak digunakan lagi. Semua utilitas yang menghasilkan ID seperti itu pada dasarnya melakukan apa yang JVM lakukan ketika ID tidak didefinisikan: mereka menghasilkan nilai berdasarkan konten file kelas, karenanya menghasilkan bilangan bulat panjang yang tidak dapat dibaca dan tidak terbaca. Jika Anda ingin masing-masing dan setiap versi kelas Anda menjadi berbeda (di mata JVM) maka Anda bahkan tidak boleh menentukan nilai serialVersionUID hanya setelah JVM akan menghasilkan satu dengan cepat, dan nilai setiap versi kelas Anda akan unik. Tujuan mendefinisikan nilai secara eksplisit adalah untuk memberi tahu mekanisme serialisasi untuk memperlakukan berbagai versi kelas yang memiliki SVUID yang sama seolah-olah mereka sama, misalnya untuk tidak menolak versi serial yang lebih lama. Jadi, jika Anda mendefinisikan ID dan tidak pernah mengubahnya (dan saya berasumsi bahwa itulah yang Anda lakukan sejak Anda mengandalkan pembuatan otomatis, dan Anda mungkin tidak pernah membuat ulang ID Anda), Anda memastikan bahwa semua - bahkan sangat berbeda - versi dari kelas Anda akan dianggap sama oleh mekanisme serialisasi. Itukah yang kamu inginkan? Jika tidak, dan jika Anda memang ingin memiliki kontrol atas bagaimana objek Anda dikenali, Anda harus menggunakan nilai-nilai sederhana yang Anda sendiri dapat mengerti dan dengan mudah memperbarui ketika Anda memutuskan bahwa kelas telah berubah secara signifikan.

Semoga ini membantu. Semoga berhasil.

Emdadul Sawon
sumber
2
Terima kasih, saya melewatkan fakta sederhana ini untuk waktu yang lama!
dedek
1
Saya benar-benar akan menghasilkan kembali serialVersionUIDdengan nomor acak baru ketika saya tidak ingin mendukung versi lama deserialization. Mungkin saya tidak perlu menggunakan angka acak tetapi bisa mulai dengan 1 dan menambahkannya. Namun, 3Ltidak berarti lagi bagi saya -3518231192373568183L. Oleh karena itu, saya kira kedua solusi bekerja dengan cara yang sama. Namun, angka acak mungkin memiliki keuntungan yang diperoleh dari sejarah non-linear dengan garpu dan cabang.
JojOatXGME
16

Untuk menghasilkan penggunaan nilai

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

dan berikan variabel templat randomLong dengan nilai berikut: groovyScript ("Random baru (). nextLong (). abs ()")

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

pharsfalvi
sumber
1
suka komentar ini, menggunakan template hidup ini pasti solusi tercepat dan paling dapat dikustomisasi (saya menghapus baris baru misalnya). Untuk mengonfigurasi, masuk ke Android Studio> Preferensi> Editor> Live Templates dan buat yang baru di sana (ikon plus) dengan nilai ini dan gunakan variabel edit untuk memasukkan skrip
hcpl
13

Selain itu Anda dapat menambahkan template langsung yang akan melakukan pekerjaan.

Untuk melakukannya tekan Ctrl+Alt+S-> "Live Templates"bagian -> other(atau jika Anda mau)

Dan kemudian buat yang baru dengan definisi seperti ini:

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

Kemudian pilih definitioncakupan dan simpan sebagai'serial'

Sekarang Anda bisa mengetikkan serialTABbadan kelas.

fallens4e
sumber
3

Cara lain untuk menghasilkan serialVersionUID adalah menggunakan >Analyze >Run Inspection by Namedari menu konteks (atau pintasan keyboard, yang ctrl+ alt+ shift+ isecara default) dan kemudian ketik "Kelas serial tanpa 'serialVersionUID'" (atau cukup ketik "serialVersionUID" dan ketik di depan Fungsi akan menemukannya untuk Anda.

Ide> Analisis> Jalankan Inspeksi berdasarkan Nama Anda kemudian akan mendapatkan menu konteks di mana Anda dapat memilih tempat menjalankan inspeksi (mis. Semua dari modul tertentu, seluruh proyek, satu file, ...)

Dengan pendekatan ini Anda bahkan tidak perlu menetapkan aturan inspeksi umum apa pun.

Alexander
sumber
Bagus, ini berhasil untukku. Itu menemukan variabel yang hilang dan disajikan opsi untuk menambahkannya.
arenaq
@arenaq senang, ini membantu orang lain ;-)
Alexander
2

Dengan versi v2018.2.1

Pergi ke

Preferensi> Editor> Inspeksi> Java> Masalah serialisasi> toggle "Kelas berseri tanpa 'serialVersionUID'".

Peringatan akan muncul di sebelah deklarasi kelas.

YLyu
sumber
1

Saya menggunakan Android Studio 2.1 dan saya memiliki konsistensi yang lebih baik untuk mendapatkan bola lampu dengan mengklik Nama kelas dan mengarahkan kursornya sebentar.

Johnny Wu
sumber
1

Tambahkan templat langsung yang disebut "ser" ke grup lain, setel ke "Berlaku di Jawa: deklarasi", dan hapus centang "Persingkat nama FQ". Berikan teks template saja:

$serial$

Sekarang edit variabel dan atur serial ke:

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

Ini mengasumsikan tata letak proyek Gradle standar. Ubah / bangun / ke / target / untuk Maven.

Greg Allen
sumber
1

Metode modern termudah: Alt+ Enteron

private static final long serialVersionUID = ;

IntelliJ akan menggarisbawahi ruang setelah =. letakkan kursor Anda di atasnya dan tekan alt+ Enter( Option+ Enterdi Mac). Anda akan mendapatkan sembulan yang mengatakan "Ubah Inisialisasi serialVersionUID secara acak". Tekan saja enter, dan itu akan mengisi ruang itu dengan panjang acak.

profilprofil
sumber
0

Jika Anda ingin menambahkan serialVersionUID yang tidak ada untuk banyak file, IntelliJ IDEA mungkin tidak berfungsi dengan baik. Saya membuat beberapa naskah sederhana untuk memenuhi tujuan ini dengan mudah:

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

Anda menyimpan skrip ini, misalnya add_serialVersionUID.shdi ~/binfolder Anda . Kemudian Anda menjalankannya di direktori root proyek Maven atau Gradle Anda seperti:

add_serialVersionUID.sh < myJavaToAmend.lst

.Lst ini menyertakan daftar file Java untuk menambahkan serialVersionUID dalam format berikut:

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

Script ini menggunakan alat JVK serialVer. Ini sangat ideal untuk situasi ketika Anda ingin mengubah sejumlah besar kelas yang tidak memiliki serialVersionUID di tempat pertama sambil mempertahankan kompatibilitas dengan kelas-kelas lama.

schnell18
sumber