11

Java シリアライゼーション クラス Mp3player extends ElectronicDevice implements Serializable このコードでは、スーパー クラス electronicdevice はシリアライズ可能に実装されていません。ここでスーパークラスもシリアライズされています。私の理解では、スーパークラスも extends のためにシリアル化されます。私の理解が正しいかどうか教えてください。

 import java.io.*;
 class ElectronicDevice { 
      ElectronicDevice() 
      {
           System.out.print("ed "); 
      }
  }
 class Mp3player extends ElectronicDevice implements Serializable {
       Mp3player() 
       { 
          System.out.print("mp "); 
       }
 }
class MiniPlayer extends Mp3player {
     MiniPlayer()
     { 
         System.out.print("mini "); 
     }
     public static void main(String[] args) {
          MiniPlayer m = new MiniPlayer();
          try {
                 FileOutputStream fos = new FileOutputStream("dev.txt");
             ObjectOutputStream os = new ObjectOutputStream(fos);
                 os.writeObject(m); os.close();

                 FileInputStream fis = new FileInputStream("dev.txt");
                 ObjectInputStream is = new ObjectInputStream(fis);
                 MiniPlayer m2 = (MiniPlayer) is.readObject(); 
                 is.close();
                 System.out.println();
          } catch (Exception x) {
                System.out.print("x "); 
          }
     }
  }
4

5 に答える 5

7

いいえ。シリアル化のプロセス中は、Serializable オブジェクトのフィールドのみが書き出され、復元されます。

javadocsによると

逆シリアル化中に、シリアル化できないクラスのフィールドは、クラスのパブリックまたは保護された引数なしのコンストラクターを使用して初期化されます。

シリアライズ可能なサブクラスのフィールドはストリームから復元されます。

この例を調べてください。
ここではありElectronicDeviceません。シリアル化プロセスで尊重されるクラスの動作のフィールドを観察してください。SerializableMp3player Serializable

import java.io.*;
class ElectronicDevice  { 
  public int i = 0;
  protected ElectronicDevice() 
  {
       System.out.println("ed "); 
  }
}
class Mp3player extends ElectronicDevice implements Serializable {
   int j =0;
   Mp3player() 
   { 
       System.out.println("mp "); 
   }
}
class MiniPlayer extends Mp3player {
  MiniPlayer()
  { 
      System.out.println("mini "); 
  }
 public static void main(String[] args) {
      MiniPlayer m = new MiniPlayer();
      m.i = 30;
      m.j = 40;
      try {
             System.out.println("i value before serialization: "+m.i);//prints 30
             System.out.println("i value before serialization: "+m.j);//prints 40
             FileOutputStream fos = new FileOutputStream("dev.txt");
             ObjectOutputStream os = new ObjectOutputStream(fos);
             os.writeObject(m); os.close();

             FileInputStream fis = new FileInputStream("dev.txt");
             ObjectInputStream is = new ObjectInputStream(fis);
             MiniPlayer m2 = (MiniPlayer) is.readObject(); 
             is.close();
             System.out.println("i value after serialization: "+m2.i);//prints o
             System.out.println("j value after serialization: "+m2.j);//prints 40
             System.out.println();
        } catch (Exception x) {
            x.printStackTrace();
            System.out.print("x "); 
       }
   }
 }
于 2013-08-24T11:54:49.580 に答える
5

スーパークラスはシリアライズ可能なコンテンツを実装していないため、スーパークラスはシリアライズされません。サブクラスのコンテンツのみがシリアル化されます。逆シリアル化すると、スーパークラスのデフォルト コンストラクターが実行され、デフォルト コンストラクターを呼び出したかのようにスーパークラスのフィールドが初期化されます。

次の例はこれを示しています。

public class SerializationTest {

    public static class Base {
        private String name;

        public Base() {
            this.name = "johnDow";
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public static class Sub extends Base implements Serializable {
        private static final long serialVersionUID = 1L;
        private String age;

        public String getAge() {
            return age;
        }

        public void setAge(String age) {
            this.age = age;
        }
    }

    public static void main(String[] args) throws Exception {
        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteArrayOS);
        Sub s = new Sub();
        s.setName("name");
        s.setAge("10");
        out.writeObject(s);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(byteArrayOS.toByteArray()));
        Sub d = (Sub) ois.readObject();
        System.out.println(d.getName() + "-" + d.getAge());
    }
}

印刷されるのは

johnDow-10
于 2013-08-24T11:44:27.393 に答える
3

これは、スーパークラスのシリアル化の規則です。

シリアライズ可能なクラスであるが、スーパークラスがシリアライズ可能でない場合、そのスーパークラスから継承したインスタンス変数は、オブジェクトの元の構築時に指定された値にリセットされます。これは、シリアル化不可能なクラス コンストラクターが実行されるためです。

したがって、いくつかのインスタンス変数を ElectronicDevice に追加する場合、スーパークラスの状態がシリアル化されないことに注意してください。(スーパークラスが Serializable を実装していない場合)

于 2013-08-24T11:52:11.533 に答える
0

私の理解では、スーパークラスも extends のためにシリアル化されます。私の理解が正しいかどうか教えてください。

簡単な答えはNOです。

Java では、すべてのクラスが のサブクラスですObjectObjectそれ自体は実装していSerializableますか?

于 2013-08-24T11:46:21.977 に答える