Eclipse mengeluarkan peringatan saat a serialVersionUID
hilang.
Kelas serialable Foo tidak menyatakan bidang serialVersionUID akhir statis jenis panjang
Apa itu serialVersionUID
dan mengapa itu penting? Tolong tunjukkan contoh di mana hilang serialVersionUID
akan menyebabkan masalah.
java
serialization
serialversionuid
ashokgelal
sumber
sumber
Jawaban:
Dokumen untuk
java.io.Serializable
penjelasan mungkin sama baiknya dengan yang akan Anda dapatkan:sumber
Jika Anda membuat cerita bersambung hanya karena Anda harus membuat cerita berseri untuk implementasi (siapa yang peduli jika Anda membuat cerita bersambung untuk
HTTPSession
, misalnya ... jika disimpan atau tidak, Anda mungkin tidak peduli tentangde-serializing
objek formulir), maka Anda dapat abaikan ini.Jika Anda benar-benar menggunakan serialisasi, itu hanya masalah jika Anda berencana untuk menyimpan dan mengambil objek menggunakan serialisasi secara langsung. Ini
serialVersionUID
mewakili versi kelas Anda, dan Anda harus menambahkannya jika versi kelas Anda saat ini tidak kompatibel dengan versi sebelumnya.Sebagian besar waktu, Anda mungkin tidak akan menggunakan serialisasi secara langsung. Jika ini masalahnya, hasilkan default
SerialVersionUID
dengan mengeklik opsi perbaikan cepat dan jangan khawatir.sumber
serialVersionUID
melindungi Anda dari perubahan yang tidak kompatibel adalah valid. Menggunakan@SuppressWarnings
dokumen niat lebih baik jika Anda tidak ingin menggunakan kelas untuk penyimpanan permanen.serialVersionUID
adalah pilihan terakhir, nasihat keputusasaan.Saya tidak bisa melewatkan kesempatan ini untuk menyambungkan buku Josh Bloch, Effective Java (2nd Edition). Bab 11 adalah sumber yang sangat diperlukan pada serialisasi Java.
Per Josh, UID yang dibuat secara otomatis dihasilkan berdasarkan nama kelas, antarmuka yang diimplementasikan, dan semua anggota publik dan yang dilindungi. Mengubah semua ini dengan cara apa pun akan mengubah
serialVersionUID
. Jadi Anda tidak perlu mengacaukannya hanya jika Anda yakin tidak ada lebih dari satu versi kelas yang akan diserialisasi (baik lintas proses atau diambil dari penyimpanan di lain waktu).Jika Anda mengabaikan mereka untuk saat ini, dan menemukan kemudian bahwa Anda perlu mengubah kelas dalam beberapa cara, tetapi mempertahankan kompatibilitas w / versi lama kelas, Anda dapat menggunakan alat JDK serialver untuk menghasilkan
serialVersionUID
pada tua kelas, dan secara eksplisit mengatur bahwa di kelas baru. (Bergantung pada perubahan Anda, Anda mungkin perlu mengimplementasikan serialisasi khusus dengan menambahkanwriteObject
danreadObject
metode - lihatSerializable
javadoc atau bab 11.)sumber
Anda bisa memberi tahu Eclipse untuk mengabaikan peringatan serialVersionUID ini:
Jika Anda tidak tahu, ada banyak peringatan lain yang dapat Anda aktifkan di bagian ini (atau bahkan ada yang dilaporkan sebagai kesalahan), banyak yang sangat berguna:
dan masih banyak lagi.
sumber
serialVersionUID
memfasilitasi versi data serial. Nilainya disimpan dengan data saat membuat serial. Saat menghapus serialisasi, versi yang sama diperiksa untuk melihat bagaimana data bersambung cocok dengan kode saat ini.Jika Anda ingin versi data Anda, Anda biasanya mulai dengan
serialVersionUID
0, dan menabraknya dengan setiap perubahan struktural ke kelas Anda yang mengubah data serial (menambah atau menghapus bidang non-transien).Mekanisme de-serialisasi bawaan (
in.defaultReadObject()
) akan menolak untuk menghilangkan serial dari data versi lama. Tetapi jika Anda mau, Anda dapat mendefinisikan readObject Anda sendiri () fungsi yang dapat membaca kembali data lama. Kode khusus ini kemudian dapat memeriksaserialVersionUID
untuk mengetahui versi data yang ada dan memutuskan bagaimana untuk menghilangkan urutannya. Teknik versi ini berguna jika Anda menyimpan data bersambung yang bertahan beberapa versi kode Anda.Tetapi menyimpan data serial untuk rentang waktu yang lama tidak terlalu umum. Adalah jauh lebih umum untuk menggunakan mekanisme serialisasi untuk secara sementara menulis data misalnya cache atau mengirimkannya melalui jaringan ke program lain dengan versi yang sama dari bagian-bagian yang relevan dari basis kode.
Dalam hal ini Anda tidak tertarik mempertahankan kompatibilitas ke belakang. Anda hanya peduli untuk memastikan bahwa basis kode yang berkomunikasi memang memiliki versi yang sama dari kelas yang relevan. Untuk memfasilitasi pemeriksaan semacam itu, Anda harus mempertahankan
serialVersionUID
seperti sebelumnya dan jangan lupa untuk memperbaruinya saat membuat perubahan pada kelas Anda.Jika Anda lupa memperbarui bidang, Anda mungkin berakhir dengan dua versi berbeda dari kelas dengan struktur yang berbeda tetapi dengan yang sama
serialVersionUID
. Jika ini terjadi, mekanisme default (in.defaultReadObject()
) tidak akan mendeteksi perbedaan, dan mencoba untuk menderialisasi data yang tidak kompatibel. Sekarang Anda mungkin berakhir dengan kesalahan runtime kriptik atau kegagalan diam (bidang nol). Jenis kesalahan ini mungkin sulit ditemukan.Jadi untuk membantu usecase ini, platform Java menawarkan Anda pilihan untuk tidak mengatur
serialVersionUID
secara manual. Sebagai gantinya, hash dari struktur kelas akan dihasilkan pada waktu kompilasi dan digunakan sebagai id. Mekanisme ini akan memastikan bahwa Anda tidak pernah memiliki struktur kelas yang berbeda dengan id yang sama, sehingga Anda tidak akan mendapatkan kegagalan serialisasi runtime yang sulit dilacak yang disebutkan di atas.Tetapi ada bagian belakang dari strategi id yang dibuat secara otomatis. Yaitu bahwa id yang dihasilkan untuk kelas yang sama mungkin berbeda di antara kompiler (seperti yang disebutkan oleh Jon Skeet di atas). Jadi, jika Anda mengkomunikasikan data serial antara kode yang dikompilasi dengan kompiler yang berbeda, disarankan untuk mempertahankan id secara manual.
Dan jika Anda kompatibel dengan data Anda seperti dalam kasus penggunaan pertama yang disebutkan, Anda juga mungkin ingin mempertahankan id sendiri. Ini untuk mendapatkan id yang dapat dibaca dan memiliki kontrol yang lebih besar tentang kapan dan bagaimana mereka berubah.
sumber
SerialVersionUID
adalah pengidentifikasi unik untuk setiap kelas,JVM
menggunakannya untuk membandingkan versi kelas memastikan bahwa kelas yang sama digunakan selama Serialisasi dilakukan selama Deserialisasi.Menentukan satu memberikan lebih banyak kontrol, meskipun JVM menghasilkan satu jika Anda tidak menentukan. Nilai yang dihasilkan dapat berbeda antara kompiler yang berbeda. Selain itu, kadang-kadang Anda hanya ingin untuk beberapa alasan untuk melarang deserialisasi objek serial lama [
backward incompatibility
], dan dalam hal ini Anda hanya perlu mengubah serialVersionUID.The javadocs untuk
Serializable
mengatakan :Oleh karena itu, Anda harus mendeklarasikan serialVersionUID karena memberi kami lebih banyak kontrol .
Artikel ini memiliki beberapa poin bagus tentang topik ini.
sumber
serialVersionUID
tanpa tahu mengapa. Komentar Tom Anderson tentang jawaban MetroidFan2002 membahas hal ini: "Saya akan mengatakan bahwa jika Anda tidak menggunakan serialisasi untuk penyimpanan permanen, Anda harus menggunakan @SuppressWarnings daripada menambahkan nilai. Ini mengacaukan kelas lebih sedikit, dan mempertahankan kemampuan dari mekanisme serialVersionUID untuk melindungi Anda dari perubahan yang tidak kompatibel. "serialVersionUID
adalah tidak sebuah 'identifier unik untuk masing-masing kelas'. Nama kelas yang sepenuhnya memenuhi syarat adalah itu. Ini adalah indikator versi .Pertanyaan orisinal menanyakan 'mengapa ini penting' dan 'contoh' di mana ini
Serial Version ID
akan berguna. Yah saya telah menemukan satu.Katakanlah Anda membuat
Car
kelas, instantiate, dan tulis itu ke aliran objek. Objek mobil rata duduk di sistem file untuk beberapa waktu. Sementara itu, jikaCar
kelas diubah dengan menambahkan bidang baru. Kemudian, ketika Anda mencoba membaca (yaitu deserialize)Car
objek yang diratakan , Anda mendapatkanjava.io.InvalidClassException
- karena semua kelas serial secara otomatis diberi pengidentifikasi unik. Pengecualian ini dilemparkan ketika pengidentifikasi kelas tidak sama dengan pengidentifikasi objek yang diratakan. Jika Anda benar-benar memikirkannya, pengecualian dilemparkan karena penambahan bidang baru. Anda dapat menghindari pengecualian ini dengan mengontrol versi sendiri dengan mendeklarasikan serialVersionUID eksplisit. Ada juga manfaat kinerja kecil dalam menyatakan secara eksplisitserialVersionUID
(karena tidak harus dihitung). Jadi, ini adalah praktik terbaik untuk menambahkan serialVersionUID Anda sendiri ke kelas Serializable Anda segera setelah Anda membuatnya seperti yang ditunjukkan di bawah ini:sumber
1
dan seterusnya.Pertama, saya perlu menjelaskan apa itu serialisasi.
Serialisasi memungkinkan untuk mengkonversi objek ke aliran, untuk mengirim objek itu melalui jaringan ATAU Simpan ke file ATAU simpan ke dalam DB untuk penggunaan huruf.
Ada beberapa aturan untuk serialisasi .
Suatu objek hanya dapat serial jika kelasnya atau superclassnya mengimplementasikan antarmuka Serializable
Objek serializable (itu sendiri mengimplementasikan antarmuka Serializable) bahkan jika superclassnya tidak. Namun, superclass pertama dalam hierarki kelas serializable, yang tidak mengimplementasikan antarmuka Serializable, HARUS memiliki konstruktor no-arg. Jika ini dilanggar, readObject () akan menghasilkan java.io.InvalidClassException di runtime
Semua tipe primitif bersifat serial.
Bidang transien (dengan pengubah sementara) BUKAN serial, (yaitu, tidak disimpan atau dikembalikan). Kelas yang mengimplementasikan Serializable harus menandai bidang transien dari kelas yang tidak mendukung serialisasi (misalnya, aliran file).
Bidang statis (dengan pengubah statis) tidak bersambung.
Ketika
Object
diserialisasi, Java Runtime mengaitkan nomor versi serial alias, theserialVersionID
.Di mana kita memerlukan serialVersionID: Selama deserialization untuk memverifikasi bahwa pengirim dan penerima kompatibel dengan serialisasi. Jika penerima memuat kelas dengan yang berbeda
serialVersionID
maka deserialization akan berakhir denganInvalidClassCastException
.Kelas serializable dapat mendeklarasikan sendiri
serialVersionUID
secara eksplisit dengan mendeklarasikan bidang bernamaserialVersionUID
yang harus statis, final, dan bertipe panjang.Mari kita coba ini dengan sebuah contoh.
Buat Obyek Serialize
Deserialize objek
CATATAN: Sekarang ubah serialVersionUID dari kelas Karyawan dan simpan:
Dan jalankan kelas Reader. Tidak mengeksekusi kelas Writer dan Anda akan mendapatkan pengecualian.
sumber
Jika Anda tidak akan perlu untuk membuat serial objek Anda ke byte array dan mengirim / menyimpannya, maka Anda tidak perlu khawatir tentang hal itu. Jika ya, maka Anda harus mempertimbangkan serialVersionUID Anda karena deserializer objek akan mencocokkannya dengan versi objek classloader-nya. Baca lebih lanjut di Spesifikasi Bahasa Jawa.
sumber
Jika Anda mendapatkan peringatan ini di kelas Anda tidak pernah berpikir tentang serialisasi, dan bahwa Anda tidak menyatakan diri Anda sendiri
implements Serializable
, itu sering kali karena Anda mewarisi dari superclass, yang mengimplementasikan Serializable. Seringkali kemudian akan lebih baik untuk mendelegasikan ke objek seperti itu daripada menggunakan warisan.Jadi, bukannya
melakukan
dan dalam metode yang relevan panggil
myList.foo()
alih-alihthis.foo()
(atausuper.foo()
). (Ini tidak cocok dalam semua kasus, tetapi masih cukup sering.)Saya sering melihat orang memperluas JFrame atau semacamnya, ketika mereka benar-benar hanya perlu mendelegasikan ini. (Ini juga membantu untuk melengkapi otomatis dalam suatu IDE, karena JFrame memiliki ratusan metode, yang tidak Anda perlukan ketika Anda ingin memanggil yang khusus di kelas Anda.)
Satu kasus di mana peringatan (atau serialVersionUID) tidak dapat dihindari adalah ketika Anda memperluas dari AbstractAction, biasanya dalam kelas anonim, hanya menambahkan metode actionPerformed-method. Saya pikir seharusnya tidak ada peringatan dalam hal ini (karena Anda biasanya tidak dapat membuat serialisasi dan deserialize kelas anonim semacam itu di berbagai versi kelas Anda), tetapi saya tidak yakin bagaimana kompiler dapat mengenali ini.
sumber
__AUTOLOAD
, yang saya tidak tahu.Untuk memahami pentingnya serialVersionUID bidang, orang harus memahami cara kerja serialisasi / deserialisasi.
Ketika objek kelas Serializable di-serialisasi, Java Runtime mengaitkan nomor versi serial (disebut sebagai serialVersionUID) dengan objek serial ini. Pada saat Anda membatalkan objek serial ini, Java Runtime cocok dengan serialVersionUID objek serial dengan serialVersionUID kelas. Jika keduanya sama maka hanya dilanjutkan dengan proses deserialisasi lebih lanjut melempar InvalidClassException.
Jadi kami menyimpulkan bahwa untuk membuat proses Serialization / Deserialization berhasil serialVersionUID objek serial harus setara dengan serialVersionUID kelas. Dalam hal jika programmer menentukan nilai serialVersionUID secara eksplisit dalam program maka nilai yang sama akan dikaitkan dengan objek serial dan kelas, terlepas dari platform serialisasi dan deserialisasi (misalnya serialisasi mungkin dilakukan pada platform seperti windows dengan menggunakan matahari atau MS JVM dan Deserialization mungkin berada pada platform Linux yang berbeda menggunakan Zing JVM).
Tetapi dalam kasus jika serialVersionUID tidak ditentukan oleh programmer maka saat melakukan Serialization \ DeSerialization objek apa pun, Java runtime menggunakan algoritma sendiri untuk menghitungnya. Algoritma perhitungan serialVersionUID ini bervariasi dari satu JRE ke yang lain. Mungkin juga bahwa lingkungan tempat objek bersambung menggunakan satu JRE (mis: SUN JVM) dan lingkungan tempat deserialisasi yang terjadi menggunakan Linux Jvm (tenaga). Dalam kasus seperti itu serialVersionUID yang terkait dengan objek serial akan berbeda dari serialVersionUID kelas yang dihitung pada lingkungan deserialisasi. Pada gilirannya deserialisasi tidak akan berhasil. Jadi untuk menghindari situasi / masalah seperti itu programmer harus selalu menentukan serialVersionUID dari kelas Serializable.
sumber
Jangan ganggu, perhitungan standarnya sangat bagus dan cukup untuk 99,9999% dari semua kasus. Dan jika Anda mengalami masalah, Anda dapat - seperti yang telah disebutkan - memperkenalkan UID sebagai pengaturan kebutuhan (yang sangat tidak mungkin)
sumber
Adapun contoh di mana serialVersionUID yang hilang dapat menyebabkan masalah:
Saya sedang mengerjakan aplikasi Java EE ini yang terdiri dari modul Web yang menggunakan
EJB
modul. Modul web memanggilEJB
modul dari jarak jauh dan melewatiPOJO
yang mengimplementasikanSerializable
sebagai argumen.Ini
POJO's
kelas dikemas dalam jar EJB dan di dalam itu jar sendiri di WEB-INF / lib dari modul web. Mereka sebenarnya kelas yang sama, tetapi ketika saya mengemas modul EJB saya membongkar botol POJO ini untuk mengemasnya bersama dengan modul EJB.Panggilan ke
EJB
gagal dengan Pengecualian di bawah ini karena saya belum menyatakannyaserialVersionUID
:sumber
Saya biasanya menggunakan
serialVersionUID
dalam satu konteks: Ketika saya tahu itu akan meninggalkan konteks Java VM.Saya akan tahu ini ketika saya menggunakan
ObjectInputStream
danObjectOutputStream
untuk aplikasi saya atau jika saya tahu perpustakaan / kerangka kerja yang saya gunakan akan menggunakannya. SerialVersionID memastikan Java VM yang berbeda dari berbagai versi atau vendor akan saling beroperasi dengan benar atau jika disimpan dan diambil di luar VM misalnyaHttpSession
data sesi dapat tetap ada bahkan selama restart dan peningkatan server aplikasi.Untuk semua kasus lain, saya menggunakan
karena sebagian besar waktu standarnya
serialVersionUID
cukup. Ini termasukException
,HttpServlet
.sumber
Data lapangan mewakili beberapa informasi yang disimpan di kelas. Kelas mengimplementasikan
Serializable
antarmuka, sehingga gerhana secara otomatis ditawarkan untuk mendeklarasikanserialVersionUID
bidang. Mari kita mulai dengan nilai 1 yang ditetapkan di sana.Jika Anda tidak ingin peringatan itu datang, gunakan ini:
sumber
Akan lebih baik jika CheckStyle dapat memverifikasi bahwa serialVersionUID pada kelas yang mengimplementasikan Serializable memiliki nilai yang baik, yaitu cocok dengan yang dihasilkan oleh generator id versi serial. Jika Anda memiliki proyek dengan banyak DTO serializable, misalnya, ingat untuk menghapus serialVersionUID yang ada dan membuat ulang itu menyakitkan, dan saat ini satu-satunya cara (yang saya tahu) untuk memverifikasi ini adalah dengan membuat ulang untuk setiap kelas dan membandingkannya dengan yang tua. Ini sangat menyakitkan.
sumber
serialver
akan diproduksi. -1serialVersionUID
ke 1. Jika versi kelas yang lebih baru tidak kompatibel, tetapi masih harus dapat menangani data lama, Anda menambah nomor versi dan menambahkan kode khusus ke berurusan dengan format yang lebih lama. Saya menangis setiap kali saya melihatserialVersionUID
lebih dari 1 digit, baik karena itu angka acak (tidak berguna) atau karena kelas tampaknya perlu berurusan dengan lebih dari 10 versi yang berbeda.SerialVersionUID digunakan untuk kontrol versi objek. Anda dapat menentukan serialVersionUID di file kelas Anda juga. Konsekuensi dari tidak menentukan serialVersionUID adalah bahwa ketika Anda menambahkan atau memodifikasi bidang apa pun di kelas maka kelas yang sudah bersambung tidak akan dapat dipulihkan karena serialVersionUID yang dihasilkan untuk kelas baru dan untuk objek serial lama akan berbeda. Proses serialisasi Java bergantung pada serialVersionUID yang benar untuk memulihkan keadaan objek serial dan melempar java.io.InvalidClassException dalam kasus ketidakcocokan serialVersionUID
Baca lebih lanjut: http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html#ixzz3VQxnpOPZ
sumber
Mengapa menggunakan
SerialVersionUID
dalamSerializable
kelas di Jawa?Selama
serialization
, Java runtime membuat nomor versi untuk suatu kelas, sehingga ia bisa menghilangkan serialisasi nanti. Nomor versi ini dikenal sebagaiSerialVersionUID
di Jawa.SerialVersionUID
digunakan untuk versi data serial. Anda hanya dapat membatalkan serialisasi kelas jikaSerialVersionUID
cocok dengan instance serial. Ketika kita tidak mendeklarasikanSerialVersionUID
di kelas kita, Java runtime menghasilkannya untuk kita tetapi itu tidak direkomendasikan. Disarankan untuk mendeklarasikanSerialVersionUID
sebagaiprivate static final long
variabel untuk menghindari mekanisme default.Ketika Anda mendeklarasikan sebuah kelas sebagai
Serializable
dengan mengimplementasikan antarmuka penandajava.io.Serializable
, Java runtime tetap instance dari kelas itu ke disk dengan menggunakan mekanisme Serialisasi default, asalkan Anda belum menyesuaikan proses menggunakanExternalizable
antarmuka.lihat juga Mengapa menggunakan SerialVersionUID di dalam kelas Serializable di Jawa
sumber
Jika Anda ingin mengubah sejumlah besar kelas yang tidak memiliki serialVersionUID di tempat pertama sambil mempertahankan kompatibilitas dengan kelas-kelas lama, alat-alat seperti IntelliJ Idea, Eclipse gagal karena mereka menghasilkan angka acak dan tidak bekerja pada banyak file dalam sekali jalan. Saya membuat skrip bash berikut (maaf untuk pengguna Windows, pertimbangkan untuk membeli Mac atau konversikan ke Linux) untuk membuat amandemen masalah serialVersionUID dengan mudah:
Anda menyimpan skrip ini, katakan add_serialVersionUID.sh kepada Anda ~ / bin. Kemudian Anda menjalankannya di direktori root proyek Maven atau Gradle Anda seperti:
.Lst ini mencakup daftar file java untuk menambahkan serialVersionUID dalam format berikut:
Script ini menggunakan alat JVK serialVer di bawah kap. Jadi pastikan $ JAVA_HOME / bin Anda ada di PATH.
sumber
Pertanyaan ini didokumentasikan dengan sangat baik di Java Efektif oleh Joshua Bloch. Buku yang sangat bagus dan wajib dibaca. Saya akan menguraikan beberapa alasan di bawah ini:
Runtime serialisasi datang dengan nomor yang disebut versi Serial untuk setiap kelas serializable. Nomor ini disebut serialVersionUID. Sekarang ada beberapa Matematika di belakang angka ini dan keluar berdasarkan bidang / metode yang didefinisikan di kelas. Untuk kelas yang sama, versi yang sama dihasilkan setiap waktu. Nomor ini digunakan selama deserialization untuk memverifikasi bahwa pengirim dan penerima objek serial telah memuat kelas untuk objek yang kompatibel sehubungan dengan serialisasi. Jika penerima telah memuat kelas untuk objek yang memiliki serialVersionUID berbeda dari kelas pengirim yang sesuai, maka deserialisasi akan menghasilkan InvalidClassException.
Jika kelas serializable Anda juga dapat mendeklarasikan serialVersionUID Anda secara eksplisit dengan mendeklarasikan bidang bernama "serialVersionUID" yang harus statis, final, dan bertipe panjang. Kebanyakan IDE seperti Eclipse membantu Anda menghasilkan string panjang itu.
sumber
Setiap kali objek diserialisasi objek dicap dengan nomor ID versi untuk kelas objek. ID ini disebut serialVersionUID dan dihitung berdasarkan informasi tentang struktur kelas. Misalkan Anda membuat kelas Karyawan dan memiliki versi id # 333 (ditugaskan oleh JVM), Sekarang ketika Anda akan membuat serial objek objek dari kelas itu (Misalkan objek Karyawan), JVM akan menetapkan UID untuknya sebagai # 333.
Pertimbangkan situasi - di masa depan Anda perlu mengedit atau mengubah kelas Anda dan dalam hal ini ketika Anda memodifikasinya, JVM akan menetapkan UID baru (Misalkan # 444). Sekarang ketika Anda mencoba untuk menghapus tanda objek objek karyawan, JVM akan membandingkan ID versi objek serial (objek Karyawan) (# 333) dengan yang ada di kelas yaitu # 444 (Karena sudah diubah). Sebagai perbandingan JVM akan menemukan kedua versi UID berbeda dan karenanya Deserialization akan gagal. Karenanya jika serialVersionID untuk setiap kelas didefinisikan oleh programmer itu sendiri. Itu akan sama bahkan jika kelas berevolusi di masa depan dan karenanya JVM akan selalu menemukan kelas yang kompatibel dengan objek berseri meskipun kelas diubah. Untuk Info lebih lanjut, Anda dapat merujuk bab 14 dari HEAD FIRST JAVA.
sumber
serialVersionUID
akan dikirimkan. Itu tidak dikirim dengan setiap objek.Penjelasan Sederhana:
Apakah Anda membuat serialisasi data?
Serialisasi pada dasarnya menulis data kelas ke file / stream / etc. De-serialisasi adalah membaca data itu kembali ke kelas.
Apakah Anda berniat untuk berproduksi?
Jika Anda hanya menguji sesuatu dengan data yang tidak penting / palsu, maka jangan khawatir tentang hal itu (kecuali jika Anda menguji serialisasi secara langsung).
Apakah ini versi pertama?
Jika demikian, atur
serialVersionUID=1L
.Apakah ini versi prod kedua, ketiga, dll.?
Sekarang Anda perlu khawatir
serialVersionUID
, dan harus memeriksanya secara mendalam.Pada dasarnya, jika Anda tidak memperbarui versi dengan benar ketika Anda memperbarui kelas yang perlu Anda tulis / baca, Anda akan mendapatkan kesalahan ketika Anda mencoba membaca data lama.
sumber
'serialVersionUID' adalah nomor 64 bit yang digunakan untuk mengidentifikasi kelas secara unik selama proses deserialisasi. Ketika Anda membuat serial objek, serialVersionUID dari kelas juga ditulis ke file. Setiap kali Anda melakukan deserialisasi objek ini, java run time mengekstrak nilai serialVersionUID ini dari data serial dan membandingkan nilai yang sama terkait dengan kelas. Jika keduanya tidak cocok, maka 'java.io.InvalidClassException' akan dibuang.
Jika kelas serializable tidak secara eksplisit mendeklarasikan serialVersionUID, maka runtime serialisasi akan menghitung nilai serialVersionUID untuk kelas tersebut berdasarkan berbagai aspek kelas seperti bidang, metode dll., Anda dapat merujuk tautan ini untuk aplikasi demo.
sumber
Untuk menyampaikan cerita panjang pendek, bidang ini digunakan untuk memeriksa apakah data serial dapat di-deserialisasi dengan benar. Serialisasi dan deserialisasi sering dilakukan oleh salinan program yang berbeda - misalnya server mengubah objek menjadi string dan klien mengubah string yang diterima menjadi objek. Bidang ini memberi tahu bahwa keduanya beroperasi dengan ide yang sama tentang apa objek ini. Bidang ini membantu ketika:
Anda memiliki banyak salinan program yang berbeda di berbagai tempat (seperti 1 server dan 100 klien). Jika Anda akan mengubah objek Anda, mengubah nomor versi Anda dan lupa untuk memperbarui satu klien ini, ia akan tahu bahwa ia tidak mampu deserialization
Anda telah menyimpan data Anda di beberapa file dan kemudian Anda mencoba membukanya dengan versi terbaru dari program Anda dengan objek yang dimodifikasi - Anda akan tahu bahwa file ini tidak kompatibel jika Anda membiarkan versi Anda benar
Kapan itu penting?
Paling jelas - jika Anda menambahkan beberapa bidang ke objek Anda, versi yang lebih lama tidak akan dapat menggunakannya karena mereka tidak memiliki bidang ini dalam struktur objek mereka.
Kurang jelas - Saat Anda menghapus objek, bidang yang tidak ada dalam string akan disimpan sebagai NULL. Jika Anda telah menghapus bidang dari objek Anda, versi yang lebih lama akan menjaga bidang ini sebagai allways-NULL yang dapat menyebabkan kesalahan perilaku jika versi yang lebih lama mengandalkan data di bidang ini (toh Anda telah membuatnya untuk sesuatu, bukan hanya untuk bersenang-senang :-))
Paling tidak jelas - Terkadang Anda mengubah ide yang Anda masukkan ke dalam beberapa bidang makna. Misalnya ketika Anda berusia 12 tahun yang Anda maksud "sepeda" di bawah "sepeda", tetapi ketika Anda berusia 18 tahun Anda berarti "sepeda motor" - jika teman Anda akan mengundang Anda untuk "bersepeda melintasi kota" dan Anda akan menjadi satu-satunya yang datang dengan sepeda, Anda akan memahami betapa pentingnya untuk menjaga makna yang sama lintas bidang :-)
sumber
Pertama untuk menjawab pertanyaan Anda, ketika kami tidak mendeklarasikan SerialVersionUID di kelas kami, Java runtime menghasilkannya untuk kami, tetapi proses itu peka terhadap banyak data meta kelas termasuk jumlah bidang, jenis bidang, pengubah akses bidang, antarmuka diimplementasikan oleh kelas dll. Oleh karena itu disarankan untuk mendeklarasikannya sendiri dan Eclipse memperingatkan Anda tentang hal yang sama.
Serialisasi: Kita sering bekerja dengan objek-objek penting yang statusnya (data dalam variabel-variabel objek) sangat penting sehingga kita tidak dapat mengambil risiko kehilangannya karena kegagalan daya / sistem (atau) kegagalan jaringan jika mengirim keadaan objek ke objek lain mesin. Solusi untuk masalah ini bernama "Persistence" yang berarti bertahan (memegang / menyimpan) data. Serialisasi adalah salah satu dari banyak cara lain untuk mencapai kegigihan (dengan menyimpan data ke disk / memori). Saat menyimpan keadaan objek, penting untuk membuat identitas objek, agar dapat membacanya kembali dengan benar (penghapusan serialisasi). Identifikasi unik ini adalah ID SerialVersionUID.
sumber
Apa itu SerialVersionUID? Jawab: - Katakanlah ada dua orang, satu dari HQ dan lainnya dari ODC, keduanya akan melakukan serialisasi dan deserialisasi masing-masing. Dalam hal ini untuk mengautentikasi bahwa penerima yang berada di ODC adalah orang yang diautentikasi, JVM membuat ID unik yang dikenal sebagai SerialVersionUID.
Berikut ini penjelasan yang bagus berdasarkan skenario,
Mengapa SerialVersionUID?
Serialisasi : Pada saat serialisasi, dengan setiap sisi pengirim objek JVM akan menyimpan Pengidentifikasi Unik. JVM bertanggung jawab untuk menghasilkan ID unik tersebut berdasarkan file .class yang sesuai yang ada dalam sistem pengirim.
Deserialization : Pada saat deserialization, pihak penerima JVM akan membandingkan ID unik yang terkait dengan Object dengan kelas ID unik yaitu JVM juga akan membuat ID unik berdasarkan file .class yang sesuai yang ada dalam sistem penerima. Jika kedua ID unik cocok maka deserialisasi hanya akan dilakukan. Kalau tidak, kita akan mendapatkan Pengecualian Runtime mengatakan InvalidClassException. Identifier unik ini tidak lain adalah SerialVersionUID
sumber