Kami bekerja keras dengan serialisasi dan harus menentukan tag Serializable pada setiap objek yang kami gunakan adalah semacam beban. Terutama saat itu adalah kelas pihak ke-3 yang tidak bisa kita ubah.
Pertanyaannya adalah: karena Serializable adalah antarmuka kosong dan Java menyediakan serialisasi yang kuat setelah Anda menambahkan implements Serializable
- mengapa mereka tidak membuat semuanya dapat diserialkan dan hanya itu?
Apa yang saya lewatkan?
java
serialization
Yoni Roit
sumber
sumber
Jawaban:
Serialisasi penuh dengan jebakan. Dukungan serialisasi otomatis dari formulir ini membuat kelas internal menjadi bagian dari API publik (itulah sebabnya javadoc memberi Anda bentuk kelas yang bertahan ).
Untuk ketekunan jangka panjang, kelas harus dapat memecahkan kode formulir ini, yang membatasi perubahan yang dapat Anda buat pada desain kelas. Ini merusak enkapsulasi.
Serialisasi juga dapat menyebabkan masalah keamanan. Dengan dapat membuat serialisasi objek apa pun yang dirujuknya, kelas dapat mengakses data yang biasanya tidak dapat diaksesnya (dengan mengurai data byte yang dihasilkan).
Ada masalah lain, seperti bentuk serial dari kelas dalam yang tidak didefinisikan dengan baik.
Membuat semua kelas dapat diserialkan akan memperburuk masalah ini. Lihat Java Edisi Kedua yang Efektif , khususnya Item 74: Implementasikan Serializable dengan bijaksana .
sumber
Saya pikir orang-orang Java dan .Net salah kali ini, akan lebih baik untuk membuat semuanya dapat diserialkan secara default dan hanya perlu menandai kelas-kelas yang tidak dapat diserialkan dengan aman.
Misalnya di Smalltalk (bahasa yang dibuat tahun 70-an) setiap objek dapat diserialkan secara default. Saya tidak tahu mengapa ini tidak terjadi di Java, mengingat fakta bahwa sebagian besar objek aman untuk diserialkan dan hanya beberapa yang tidak.
Menandai objek sebagai dapat diserialkan (dengan antarmuka) tidak secara ajaib membuat objek itu dapat diserialkan, itu dapat diserialkan selama ini , hanya saja sekarang Anda mengungkapkan sesuatu yang dapat ditemukan sistem sendiri, jadi saya tidak melihat alasan yang benar-benar bagus untuk serialisasi menjadi seperti sekarang.
Saya pikir itu adalah keputusan buruk yang dibuat oleh desainer atau serialisasi adalah renungan, atau platform tidak pernah siap untuk melakukan serialisasi secara default pada semua objek dengan aman dan konsisten.
sumber
Serializable
trik adalah salah satu keputusan lain yang salah yang telah diambil satu atau dua dekade yang lalu, dan satu lagi Selain jengkel ketika berhadapan dengan java murni, seperti beberapa kelemahan dalam pengumpulan dan tali pengolahan di perpustakaan standar. Syukurlah ada Kryo, tapi itu ketergantungan dan kita perlu menemukannya terlebih dahulu. Beginilah seharusnya serialisasi built-in dilakukan.Tidak semuanya benar-benar dapat serial. Ambil koneksi soket jaringan, misalnya. Anda dapat membuat serialisasi data / status objek soket Anda, tetapi inti dari koneksi aktif akan hilang.
sumber
implements NotSerializable
:)Peran utama Serializable di Java adalah untuk benar-benar membuat, secara default, semua objek lain tidak dapat dialirkan. Serialisasi adalah mekanisme yang sangat berbahaya, terutama dalam implementasi defaultnya. Karenanya, seperti persahabatan di C ++, ini dinonaktifkan secara default, meskipun biayanya sedikit untuk membuatnya dapat diserialkan.
Serialisasi menambah kendala dan potensi masalah karena kompatibilitas struktur tidak diasuransikan. Itu bagus karena dimatikan secara default.
Saya harus mengakui bahwa saya telah melihat sangat sedikit kelas nontrivial di mana serialisasi standar melakukan apa yang saya inginkan. Terutama dalam kasus struktur data yang kompleks. Jadi upaya yang Anda habiskan untuk membuat kelas dapat berseri dengan benar mengurangi biaya penambahan antarmuka.
sumber
Untuk beberapa kelas, terutama yang mewakili sesuatu yang lebih fisik seperti File, Socket, Thread, atau koneksi DB, sama sekali tidak masuk akal untuk membuat serial instans. Bagi banyak orang lain, Serialisasi mungkin bermasalah karena menghancurkan batasan keunikan atau hanya memaksa Anda untuk menangani contoh versi berbeda dari kelas, yang mungkin tidak Anda inginkan.
Bisa dibilang, mungkin lebih baik untuk membuat semuanya Serializable secara default dan membuat kelas non-serializable melalui antarmuka kata kunci atau penanda - tapi kemudian, mereka yang harus menggunakan opsi itu mungkin tidak akan memikirkannya. Begitulah, jika Anda perlu mengimplementasikan Serializable, Anda akan diberi tahu oleh Exception.
sumber
Saya pikir pemikiran itu adalah untuk memastikan Anda, sebagai programmer, tahu bahwa objek Anda adalah serialisasi.
sumber
Rupanya semuanya dapat diserialkan dalam beberapa desain awal, tetapi karena masalah keamanan dan kebenaran, desain akhir berakhir seperti yang kita semua tahu.
Sumber: Mengapa kelas harus mengimplementasikan Serializable agar dapat ditulis ke ObjectOutputStream? .
sumber
Harus menyatakan secara eksplisit bahwa instance dari kelas tertentu dapat berseri, bahasa memaksa Anda untuk memikirkan apakah Anda harus mengizinkannya. Untuk serialisasi objek nilai sederhana itu sepele, tetapi dalam kasus yang lebih kompleks Anda harus benar-benar memikirkan semuanya.
Dengan hanya mengandalkan dukungan serialisasi standar JVM, Anda dapat menghadapi semua jenis masalah pembuatan versi yang tidak menyenangkan.
Keunikan, referensi ke sumber daya 'nyata', pengatur waktu, dan banyak jenis artefak BUKAN untuk serialisasi.
sumber
Baca ini untuk memahami Antarmuka Serializable dan mengapa kita harus membuat hanya beberapa kelas Serializable dan juga kita harus berhati-hati di mana menggunakan kata kunci sementara jika kita ingin menghapus beberapa bidang dari prosedur penyimpanan.
http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/
sumber
Jawaban saya adalah ini bukan alasan yang bagus. Dan dari komentar Anda, saya dapat melihat bahwa Anda telah mempelajarinya. Bahasa lain dengan senang hati mencoba membuat serialisasi segala sesuatu yang tidak melompat pada pohon setelah Anda menghitung sampai 10. Sebuah Objek harus default menjadi serializable.
Jadi, yang pada dasarnya perlu Anda lakukan adalah membaca semua properti kelas pihak ketiga Anda sendiri. Atau, jika itu adalah pilihan untuk Anda: dekompilasi, masukkan kata kunci sialan itu di sana, dan kompilasi ulang.
sumber
Ada beberapa hal di Java yang tidak dapat diserialkan karena bersifat spesifik waktu proses. Hal-hal seperti aliran, utas, runtime, dll. Dan bahkan beberapa kelas GUI (yang terhubung ke OS yang mendasarinya) tidak dapat diserialkan.
sumber
Sementara saya setuju dengan poin yang dibuat dalam jawaban lain di sini, masalah sebenarnya adalah dengan deserialisation: Jika definisi kelas berubah maka ada risiko nyata deserialisation tidak akan berhasil. Tidak pernah mengubah bidang yang ada adalah komitmen utama yang harus dibuat oleh penulis perpustakaan! Mempertahankan kompatibilitas API sudah cukup menjadi tugas yang berat.
sumber
Kelas yang perlu dipertahankan ke file atau media lain harus mengimplementasikan antarmuka yang dapat diserialisasi, sehingga JVM dapat mengizinkan objek kelas untuk diserialkan. Mengapa kelas Objek tidak serialisasi maka tidak ada kelas yang perlu mengimplementasikan antarmuka, setelah semua JVM membuat serial kelas hanya ketika saya menggunakan ObjectOutputStream yang berarti kontrol masih di tangan saya untuk membiarkan JVM untuk membuat serial.
Alasan mengapa kelas Objek tidak dapat diserialkan secara default dalam kenyataan bahwa versi kelas adalah masalah utama. Oleh karena itu, setiap kelas yang tertarik dengan serialisasi harus ditandai sebagai Serializable secara eksplisit dan memberikan nomor versi serialVersionUID.
Jika serialVersionUID tidak tersedia, kami mendapatkan hasil yang tidak diharapkan saat melakukan deserialisasi objek, itulah sebabnya JVM menampilkan InvalidClassException jika serialVersionUID tidak cocok. Oleh karena itu setiap kelas harus mengimplementasikan antarmuka Serializable dan menyediakan serialVersionUID untuk memastikan Kelas yang disajikan di kedua ujungnya identik.
sumber