Java Academy · Pelajaran

Pensirilan Tersuai: writeObject dan readObject

Gantikan writeObject dan readObject untuk penyulitan, pemampatan atau pengendalian medan tersuai.

Pelajaran 3 daripada 413 langkah

Pensirilan Tersuai: writeObject dan readObject ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Apabila Serialisasi Lalai Tidak Mencukupi

Serialisasi lalai menyimpan semua medan bukan transient sebagaimana adanya. Kadangkala anda memerlukan penyulitan, pemampatan atau perwakilan yang berbeza. Di sinilah cangkuk writeObject / readObject digunakan.

Mengisytiharkan writeObject

Tambahkan kaedah private void writeObject(ObjectOutputStream oos). Java memanggil kaedah ini dan bukannya mekanisme lalai. Anda mengawal dengan tepat perkara yang ditulis.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject(); // write non-transient fields normally
    oos.writeUTF(encrypt(this.secret)); // write encrypted secret
}

Mengisytiharkan readObject

Tambahkan kaedah private void readObject(ObjectInputStream ois). Java memanggil kaedah ini semasa penyahserialan. Anda membaca data dalam susunan yang sama tepat seperti susunan penulisannya.

private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject(); // restore non-transient fields
    this.secret = decrypt(ois.readUTF()); // decrypt and restore
}

Susunan Penting

Apa sahaja yang anda tulis dalam writeObject mesti dibaca semula dalam susunan yang sama dalam readObject. Susunan yang tidak sepadan menyebabkan StreamCorruptedException.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.writeInt(version);
    oos.writeUTF(data);
}
private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    this.version = ois.readInt();  // same order
    this.data    = ois.readUTF();
}

Memampatkan Data Semasa Serialisasi

Bungkus aliran dengan GZIPOutputStream dalam writeObject untuk memampatkan medan besar, kemudian gunakan GZIPInputStream dalam readObject untuk menyahmampatkannya.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try (GZIPOutputStream gz = new GZIPOutputStream(bos)) {
        gz.write(largePayload.getBytes());
    }
    oos.writeObject(bos.toByteArray());
}

Cangkuk readResolve

readResolve() dipanggil selepas penyahserialan. Pulangkan objek pengganti — berguna untuk singleton dan enum bagi memastikan hanya satu instans wujud selepas penyahserialan.

public class AppConfig implements Serializable {
    private static final AppConfig INSTANCE = new AppConfig();
    private AppConfig() {}
    public static AppConfig getInstance() { return INSTANCE; }
    private Object readResolve() { return INSTANCE; } // return singleton
}

Cangkuk writeReplace

writeReplace() dipanggil sebelum serialisasi. Pulangkan objek lain untuk diserialkan sebagai gantinya — berguna untuk pola proksi dan pengganti serialisasi.

private Object writeReplace() {
    return new UserProxy(this.id); // serialize a lightweight proxy
}

Mengesahkan Medan dalam readObject

Anda boleh menambahkan logik pengesahan dalam readObject untuk menolak data yang tidak sah atau telah diusik sebagai sebahagian daripada strategi pertahanan berlapis.

private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    if (age < 0 || age > 150) {
        throw new InvalidObjectException("Invalid age: " + age);
    }
}

Mengendalikan Perubahan Versi

Gunakan medan versi dalam writeObject supaya readObject boleh mengendalikan format lama dan baharu dengan baik semasa pemindahan.

private static final int SERIAL_VERSION = 2;
private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    oos.writeInt(SERIAL_VERSION);
    if (SERIAL_VERSION >= 2) oos.writeUTF(email); // new field
}
private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    int v = ois.readInt();
    if (v >= 2) this.email = ois.readUTF();
}

Pola Proksi Serialisasi

Pendekatan yang kukuh: tulis kelas dalaman statik peribadi yang menangkap keadaan minimum, kemudian gunakan writeReplace untuk menulis proksi dan readResolve proksi itu untuk membina semula objek asal.

Pertimbangan Prestasi

Serialisasi tersuai menambah lebihan masa panggilan kaedah tetapi boleh mengurangkan saiz muatan dengan ketara. Jalankan penanda aras sebelum mengoptimumkan; gunakan Externalizable untuk kawalan maksimum.

Semakan Pantas

Apakah yang mesti benar tentang susunan dalam writeObject dan readObject?

Imbas Kembali

Gantikan writeObject / readObject untuk penyulitan, pemampatan atau format tersuai. Gunakan readResolve untuk singleton. Sentiasa membaca dalam susunan yang sama seperti susunan penulisan.

Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
104
Pelajaran
374

Soalan Lazim

Adakah pelajaran “Pensirilan Tersuai: writeObject dan readObject” percuma?

Ya — teks penuh “Pensirilan Tersuai: writeObject dan readObject” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Pensirilan Tersuai: writeObject dan readObject”?

Gantikan writeObject dan readObject untuk penyulitan, pemampatan atau pengendalian medan tersuai. Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Java Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Pensirilan Tersuai: writeObject dan readObject” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Asas Pensirilan Java
  2. Medan transient dan serialVersionUID
  3. Pensirilan Tersuai: writeObject dan readObject
  4. Alternatif Moden: JSON dan Protocol Buffers
← Kembali ke Java Academy