在java序列化类中,Mp3player扩展了ElectronicDevice实现Serializable,在这段代码中,超类electronicdevice未实现可序列化。这里超类也被序列化了。我的理解是超级类也因为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 ");
}
}
}
答案 0 :(得分:6)
否。在序列化过程中只会写出并恢复Serializable对象的字段。
根据javadocs
在反序列化期间,将使用类的public或protected no-arg构造函数初始化非可序列化类的字段。
将从流中恢复可序列化子类的字段。
请看这个例子
此处ElectronicDevice
不是Serializable
,其中Mp3player
是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 ");
}
}
}
答案 1 :(得分:5)
由于超类没有实现超类的Serializable内容,所以不会被序列化。只有子类的内容才会被序列化。反序列化时,超类的默认构造函数将被执行,超类的字段将被初始化,就像调用默认构造函数一样。
以下示例说明了这一点。
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
答案 2 :(得分:1)
这是超类序列化的规则:
如果您是可序列化的类,但您的超类不是 可序列化,然后是你从那里继承的任何实例变量 超类将被重置为它们在给定期间给出的值 原始构造的对象。这是因为 不可序列化的类构造函数将运行。
因此,如果向ElectronicDevice添加一些实例变量,请注意超类的状态不会被序列化。 (除非超类实现Serializable)
答案 3 :(得分:0)
我的理解是超类也被序列化了 我知道我的理解是否正确。
简短的回答是否。
在java中,每个类都是Object
的子类。 Object
本身是否实施Serializable
?
答案 4 :(得分:0)
为了允许序列化非序列化类的子类型,子类型可能负责保存和恢复超类型的公共,受保护和(如果可访问)包字段的状态“
参考 - http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html