Rumah  >  Soal Jawab  >  teks badan

java - Mengapa Kelas yang ditakrifkan dalam Serializable tidak boleh bersiri?

Medan dalam kelas Boleh Bersiri mestilah sama ada Boleh Bersiri atau sementara walaupun kelas itu tidak pernah bersiri atau dinyahsiri secara eksplisit. Ini kerana di bawah beban, kebanyakan rangka kerja aplikasi J2EE menyiram objek ke cakera dan objek yang dikatakan Boleh Bersiri dengan ahli data tidak sementara dan tidak boleh disiri boleh menyebabkan ranap program dan membuka pintu kepada penyerang.

Peraturan ini menimbulkan isu mengenai medan tidak boleh bersiri dan medan koleksi apabila ia bukan peribadi (kerana ia boleh diberikan nilai tidak boleh bersiri secara luaran), dan apabila ia diberikan jenis tidak boleh bersiri dalam kelas.

Contoh Kod Tidak Mematuhi

public class Address {
  //...
}

public class Person implements Serializable {
  private static final long serialVersionUID = 1905122041950251207L;

  private String name;
  private Address address;  // Noncompliant; Address isn't serializable
}
欧阳克欧阳克2667 hari yang lalu1217

membalas semua(2)saya akan balas

  • 扔个三星炸死你

    扔个三星炸死你2017-06-30 09:58:37

    Apabila objek disiri, mengikut peraturan penyirian lalai Java, semua ahli dalam objek mesti bersiri Maksudnya, Kelas ini mesti melaksanakan Serializable.

    Jadi, anda mempunyai dua cara untuk mengubah suainya Satu ialah melaksanakan antara muka Boleh Bersiri dalam Alamat, dan satu lagi ialah menambah tanda transient pada ahli alamat secara Orang supaya ahli itu tidak bersiri.

    balas
    0
  • typecho

    typecho2017-06-30 09:58:37

    Jika ahli alamat perlu bersiri, kelas Alamat juga perlu melaksanakan antara muka Serializable.
    Jika ahli alamat tidak perlu bersiri, anda boleh menambah kata kunci transient, maka ahli alamat tidak akan bersiri dan nilainya adalah batal. Seperti berikut:

    public class Person implements Serializable {
      private static final long serialVersionUID = 1905122041950251207L;
    
      private String name;
      private transient Address address;  // Noncompliant; Address isn't serializable
    }

    Sudah tentu terdapat cara lain:
    Sebagai contoh, melaksanakan antara muka Externalizable dan mengatasi kaedah readExternal(ObjectInput in) dan writeExternal(ObjectOutput out).
    Terdapat juga pelaksanaan alternatif kaedah antara muka Externalizable, atau melaksanakan antara muka Serializable, menambah writeObject(ObjectOutputStream obs) dan readObject(ObjectInputStream ois).


    Beritahu saya sekali lagi mengapa Alamat mesti melaksanakan Serializable, atau tambahkan kata kunci transient Orang untuk disirikan?
    Mari kita lihat dahulu pengecualian yang dilemparkan dengan menggunakan ObjectOutputStream untuk mengekalkan objek tanpa memproses

    Exception in thread "main" java.io.NotSerializableException

    Lihat ObjectOutputStreamKod sumber:

    /**
         * Underlying writeObject/writeUnshared implementation.
         */
        private void writeObject0(Object obj, boolean unshared)
            throws IOException
        {
                //......
                // remaining cases
                if (obj instanceof String) {
                    writeString((String) obj, unshared);
                } else if (cl.isArray()) {
                    writeArray(obj, desc, unshared);
                } else if (obj instanceof Enum) {
                    writeEnum((Enum<?>) obj, desc, unshared);
                } else if (obj instanceof Serializable) {
                    writeOrdinaryObject(obj, desc, unshared);
                } else {
                    if (extendedDebugInfo) {
                        throw new NotSerializableException(
                            cl.getName() + "\n" + debugInfoStack.toString());
                    } else {
                        throw new NotSerializableException(cl.getName());
                    }
                }
            } finally {
                depth--;
                bout.setBlockDataMode(oldMode);
            }
        }

    Dapat dilihat daripada ini bahawa jika jenis objek yang ditulis ialah String, Array, Enum, atau Serializable, ia boleh bersiri, jika tidak NotSerializableException akan dilemparkan. Dan apabila mensiri objek, bukan sahaja objek semasa itu sendiri akan bersiri, tetapi objek lain yang dirujuk oleh objek itu juga akan bersiri.

    balas
    0
  • Batalbalas