简体   繁体   English

扩展类的Java序列化

[英]Java Serialization for Extended Class

In java serialization class Mp3player extends ElectronicDevice implements Serializable in this code super class electronicdevice is not implemented serializable. 在java序列化类中,Mp3player扩展了ElectronicDevice实现Serializable,在这段代码中,超类electronicdevice未实现可序列化。 here super class is also getting serialized. 这里超类也被序列化了。 my understanding is super class is also gets serialized due to extends.let me know my understanding is correct or not. 我的理解是超级类也因为extends.let而被序列化。我知道我的理解是否正确。

 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 "); 
          }
     }
  }

No.During the process of serialization only the fields of Serializable objects are written out and restored. 在序列化过程中, 只会写出并恢复Serializable对象的字段。

According to javadocs 根据javadocs

During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. 在反序列化期间,将使用类的public或protected no-arg构造函数初始化非可序列化类的字段。

Where as the fields of serializable subclasses will be restored from the stream. 其中可序列化子类的字段将从流中恢复。

Please look into this example 请看这个例子
Here ElectronicDevice is not Serializable ,where as Mp3player is Serializable .Observe the fields of respected classes behaviour in serialization process. 这里ElectronicDevice不是Serializable ,其中Mp3playerSerializable 。在序列化过程中观察受尊重的类行为的字段。

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 "); 
       }
   }
 }

Since super class doesn't implement Serializable contents of the super class wont get serialized. 由于超类没有实现超类的Serializable内容不会被序列化。 Only the contents of the subclass would get serialized. 只有子类的内容才会被序列化。 When you deserialize the default constructor of the superclass would get executed and the fields of the superclass initialized as if you invoked the default constructor. 反序列化时,超类的默认构造函数将被执行,超类的字段将被初始化,就像调用默认构造函数一样。

Following example illustrates this. 以下示例说明了这一点

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());
    }
}

What gets printed is 打印的是什么

johnDow-10

This is the rule for superclass serialization: 这是超类序列化的规则:

If you are a serializable class, but your superclass is NOT serializable, then any instance variables you INHERIT from that superclass will be reset to the values they were given during the original construction of the object. 如果您是一个可序列化的类,但您的超类不可序列化,那么您从该超类INHERIT的任何实例变量将被重置为在该对象的原始构造期间给出的值。 This is because the nonserializable class constructor WILL run. 这是因为非可序列化的类构造函数将运行。

Therefore, if you add some instance variables to ElectronicDevice, be aware that the superclass 's state will be not serialized. 因此,如果向ElectronicDevice添加一些实例变量,请注意超类的状态不会被序列化。 (unless the superclass implements Serializable) (除非超类实现Serializable)

my understanding is super class is also gets serialized due to extends.let me know my understanding is correct or not. 我的理解是超级类也因为extends.let而被序列化。我知道我的理解是否正确。

The short answer is NO . 简短的回答是否定的

In java, every class is a subclass of Object . 在java中,每个类都是Object的子类。 Does Object itself implement Serializable ? Object本身是否实现Serializable

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields” 为了允许序列化非可序列化类的子类型,子类型可能负责保存和恢复超类型的public,protected和(如果可访问的)包字段的状态“

Reference - http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html 参考 - http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM