Artikel ini menjelaskan serialisasi objek dan deserialisasi di Java. Bagikan untuk semua orang untuk referensi Anda. Dengan rincian sebagai berikut:
1. Pendahuluan
Serialisasi objek mengacu pada proses mengubah objek menjadi urutan byte, sedangkan deserialisasi adalah proses memulihkan objek berdasarkan urutan byte.
Serialisasi umumnya digunakan dalam skenario berikut:
1. Simpan objek secara permanen dan simpan urutan byte objek ke file lokal;
2. Lewati objek dalam jaringan dengan membuat serial;
3. Lulus objek antar proses melalui serialisasi.
Kelas tempat objek tersebut harus mengimplementasikan antarmuka yang dapat diserialisasi atau dapat dieksternalisasi untuk diserialisasi. Untuk kelas yang menerapkan antarmuka serial, serialisasi dan deserialisasi mengadopsi metode serialisasi default.
Java.io.objectOutputStream mewakili aliran output objek, dan metodenya writeObject (objek OBJ) dapat mewujudkan serialisasi objek dan menulis urutan byte yang diperoleh ke aliran output target.
Java.io.objectInputStream mewakili aliran input objek, dan metode readObject () dapat membaca urutan byte dari aliran input sumber, deserialisasi menjadi objek, dan mengembalikannya.
2. Beberapa cara untuk membuat serial
Misalkan kelas pelanggan didefinisikan, tergantung pada metode serialisasi pelanggan, mungkin ada metode serialisasi berikut:
1. Menerapkan metode ReadObject dan WriteObject Serializable, tidak terdefinisi
ObjectOutputStream menggunakan JDK untuk membuat serialisasi variabel instance yang tidak benar dari objek pelanggan secara default;
ObjectInputStream Deserializes variabel instance non-transsient objek pelanggan menggunakan metode default JDK.
2. Menerapkan Serializable dan Tentukan Metode ReadObject dan WriteObject
ObjectOutputStream Metode WriteObject (ObjectOutputStream out) dari kelas pelanggan untuk membuat serialisasi variabel instance non-transsient dari objek pelanggan;
ObjectInputStream Metode ReadObject (ObjectInputStream in) dari kelas pelanggan untuk deserialize variabel instance non-transsient dari objek pelanggan.
3. Menerapkan Eksternalisasi, Tentukan Metode ReadExternal dan WriteExternal
ObjectOutputStream memanggil metode WriteExternal dari kelas pelanggan untuk membuat serialisasi variabel instance yang tidak benar dari objek pelanggan;
ObjectInputStream First Instantiates suatu objek melalui konstruktor tanpa parameter dari kelas pelanggan, dan kemudian deserialisasi variabel instance yang tidak benar dari objek pelanggan menggunakan metode ReadExternal.
3. Antarmuka Serializable
Kelas memungkinkan fungsi serialisasi dengan mengimplementasikan antarmuka java.io.serializable. Kelas yang tidak mengimplementasikan antarmuka ini tidak akan dapat membuat serialisasi atau deserialisasi negara bagian mereka. Semua subtipe dari kelas serial itu sendiri dapat diserializable. Antarmuka serialisasi tidak memiliki metode atau bidang dan hanya digunakan untuk mengidentifikasi semantik yang dapat serial.
Selama proses deserialisasi, bidang kelas yang tidak serial akan diinisialisasi menggunakan konstruktor parameter yang umum atau dilindungi dari kelas. Subkelas yang dapat di -serialisasi harus dapat mengakses konstruktor tanpa parameter. Bidang yang dapat menjadi subclass yang dapat diserialisasi akan dipulihkan dari aliran.
Saat melintasi tampilan kelas, Anda dapat menemukan objek yang tidak mendukung antarmuka serial yang dapat diseriali. Dalam hal ini, Notserializable Exception dilemparkan dan kelas yang tidak dapat diidentifikasi.
1. Tanda tangan yang akurat
Kelas yang membutuhkan pemrosesan khusus selama serialisasi dan deserialisasi harus mengimplementasikan metode khusus menggunakan tanda tangan akurat berikut:
private void writeObject (java.io.objectOutputStream out) melempar ioException
private void readObject (java.io.objectInputStream in) melempar ioException, ClassNotFoundException;
private void readObjectNodata () melempar objekStreamException;
Metode WriteObject bertanggung jawab untuk menulis status objek kelas tertentu sehingga metode ReadObject yang sesuai dapat mengembalikannya. Mekanisme default untuk menyimpan bidang objek dapat dipanggil dengan memanggil. DefaultWriteObject. Metode itu sendiri tidak perlu melibatkan negara bagian yang termasuk superclass atau subkelasnya. Status dapat disimpan dengan menulis bidang individual ke ObjectOutputStream menggunakan metode WriteObject atau menggunakan metode yang didukung oleh DataOutput untuk tipe data dasar.
Metode ReadObject bertanggung jawab untuk membaca dan memulihkan bidang kelas dari aliran. Ini dapat memanggil. Metode DeFaultreadObject menggunakan informasi dalam aliran untuk mengalokasikan bidang objek dalam aliran yang disimpan melalui bidang yang ditentukan yang sesuai dalam objek saat ini. Ini digunakan untuk menangani situasi di mana bidang baru perlu ditambahkan setelah evolusi kelas. Metode itu sendiri tidak perlu melibatkan negara bagian yang termasuk superclass atau subkelasnya. Status dapat disimpan dengan menulis bidang individual ke ObjectOutputStream menggunakan metode WriteObject atau menggunakan metode yang didukung oleh DataOutput untuk tipe data dasar.
Dalam kasus di mana aliran serialisasi tidak mencantumkan kelas yang diberikan sebagai superclass untuk deserialized, metode ReadObjectNodata bertanggung jawab untuk menginisialisasi keadaan objek dari kelas tertentu. Ini terjadi ketika kelas instance deserialized yang digunakan oleh penerima berbeda dari pengirim dan kelas yang diperluas oleh versi penerima bukanlah kelas yang diperpanjang oleh versi pengirim. Ini juga terjadi ketika aliran serialisasi telah dirusak;
Saat menulis objek ke aliran, Anda perlu menentukan kelas serial dari objek alternatif yang akan digunakan, dan Anda harus mengimplementasikan metode khusus ini dengan tanda tangan yang akurat:
Objek apa pun-modifier objek Writerplace () melempar ObjectStreamException;
Metode Writerplace ini akan dipanggil dengan serialisasi, asalkan jika metode ini ada, dan dapat diakses dengan metode yang ditentukan dalam kelas objek serial. Oleh karena itu, metode ini dapat memiliki akses pribadi, terlindungi, dan paket-pribadi. Akses subkelas ke metode ini mengikuti aturan akses Java.
Saat membaca instance kelas dari aliran, Anda perlu menentukan tanda tangan yang tepat yang harus digunakan oleh kelas alternatif untuk mengimplementasikan metode khusus ini.
Any-access-modifier objek readResolve () melempar objectStreamException;
Metode ReadResolve ini mengikuti aturan panggilan yang sama dan aturan akses sebagai Writerplace.
Jika kelas mendefinisikan metode ReadResolve, maka metode ReadResolve akan dipanggil pada akhir deserialisasi, dan objek yang dikembalikan dengan metode ini adalah hasil akhir dari deserialisasi.
2.SerialVersionuid
Runtime serialisasi menggunakan nomor versi yang disebut SerialVersionuid untuk bergaul dengan setiap kelas Serializable, yang digunakan selama deserialisasi untuk memverifikasi bahwa pengirim dan penerima objek serial yang dimuat untuk objek tersebut. Jika penerima memuat serialversionuid dari kelas objek yang berbeda dari nomor versi pengirim yang sesuai, deserialisasi akan menghasilkan InvalidClassException. Kelas serializable dapat secara eksplisit mendeklarasikan serialversionuid sendiri dengan mendeklarasikan bidang bernama "serialversionuid" (bidang itu harus merupakan bidang panjang yang statis):
Serialversionuid final static-modifier statis long static = 42L;
Jika kelas serializable tidak secara eksplisit menyatakan serialversionuid, runtime serialisasi menghitung nilai serialversionuid default dari kelas berdasarkan berbagai aspek kelas, seperti yang dijelaskan dalam spesifikasi serialisasi objek "Java (TM)". Namun, sangat disarankan agar semua kelas serializable secara eksplisit menyatakan nilai serialversionuid, karena perhitungan serialversionuid default sangat sensitif terhadap rincian kelas, dan dapat sangat bervariasi tergantung pada implementasi kompiler, jadi dalam proses deserialisasi yang tidak terduga yang tidak dapat diatasi dengan pelepasan yang tidak terduga. dapat terjadi. Oleh karena itu, untuk memastikan konsistensi antara nilai serialversionuid di berbagai kompiler Java, kelas serial harus menyatakan nilai serialversionuid eksplisit. Juga sangat disarankan untuk menggunakan pengubah pribadi untuk menampilkan SerialVersionuid Deklarasi jika memungkinkan karena deklarasi tersebut hanya digunakan untuk secara langsung mendeklarasikan kelas - bidang serialversionuid sebagai anggota yang diwariskan tidak ada gunanya. Kelas array tidak dapat mendeklarasikan eksplisit serialversionuid, sehingga mereka selalu memiliki nilai yang dihitung default, tetapi kelas array tidak cocok dengan persyaratan nilai serialversionuid.
3. Antarmuka yang dapat dieksternalisasi
Eksternalisasi adalah perpanjangan dari serailzable.
Sebut metode kelas WriteExternal selama serialisasi, dan deserialize metode ReadExternal;
Saat melakukan deserialisasi, konstruktor tanpa parameter ini disebut terlebih dahulu, yang berbeda dari deserialisasi default.
Keempat, ringkasan
Jika metode serialisasi default diadopsi, selama kelas mengimplementasikan antarmuka serializable, contohnya dapat diserialisasi. Secara umum, kelas yang dirancang khusus untuk warisan harus mencoba untuk tidak mengimplementasikan antarmuka yang dapat diserialisasi, karena begitu kelas induk mengimplementasikan antarmuka yang dapat diserialisasi, semua subclass -nya dapat serial.
Kekurangan metode serialisasi default:
1. Tidak aman untuk secara langsung membuat serialisasi data sensitif yang tidak cocok untuk pengungkapan objek;
2. Ia tidak akan memeriksa apakah variabel anggota objek memenuhi kendala yang benar, dan dapat dirusak dengan data dan menyebabkan operasi abnormal;
3. Traversal rekursif dari grafik objek diperlukan.
4. Buat antarmuka kelas dibatasi oleh implementasi internal kelas, membatasi peningkatan dan pemeliharaan kelas.
Dengan mengimplementasikan tipe pribadi writeObject () dan readObject () dari antarmuka serializable, atau mengimplementasikan antarmuka yang dapat dieksternalisasi, mengimplementasikan metode WriteExternal () dan ReadExternal (), dan menyediakan dua cara konstruktor parameter tipe publik untuk mengontrol proses serialisasi itu, dan memberikan tipe publik yang tidak memiliki parameter cara untuk mengontrol proses serialisasi itu, dan memberikan tipe publik tanpa parameter Parameter untuk mengontrol proses serialisasi dapat secara efektif menghindari kekurangan metode serialisasi default.
Diharapkan bahwa artikel ini bermanfaat untuk desain program Java semua orang.