java中序列化與反序列化的冷知識(shí)
來源:程序員人生 發(fā)布時(shí)間:2015-01-06 08:55:34 閱讀次數(shù):2551次
轉(zhuǎn)載請(qǐng)注明出處:http://blog.csdn.net/zhaokaiqiang1992
關(guān)于甚么是序列化,和為何要序列化的知識(shí)就不再論述了,本文主要探討1些特殊點(diǎn)的情況。
1.java中如何實(shí)現(xiàn)序列化和反序列化
下面的代碼是進(jìn)行序列化的簡(jiǎn)單實(shí)例
public static void main(String[] args) {
System.out.println("-----------------序列化----------------------↓");
Student student1 = new Student(10, "zhao");
Student student2 = new Student(15, "kai");
Student student3 = new Student(20, "qiang");
ObjectOutputStream objectWriter = null;
try {
objectWriter = new ObjectOutputStream(new FileOutputStream(
new File("./Serializable")));
objectWriter.writeObject(student1);
objectWriter.writeObject(student2);
objectWriter.writeObject(student3);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
objectWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("-----------------反序列化----------------------↓");
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(new FileInputStream(
new File("./Serializable")));
Student s1 = (Student) objectInputStream.readObject();
Student s2 = (Student) objectInputStream.readObject();
Student s3 = (Student) objectInputStream.readObject();
System.out.println(s1.toString());
System.out.println(s2.toString());
System.out.println(s3.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.在反序列化的時(shí)候,需要調(diào)用本類的構(gòu)造函數(shù)嗎? 我的測(cè)試序列化的類以下,在無參和有參的構(gòu)造函數(shù)中,打印了語句,然后,我們使用上面的序列化和反序列化代碼進(jìn)行測(cè)試。
public class Student implements Serializable {
private int age;
private String name;
public Student() {
System.out.println("Student()");
}
public Student(int age, String name) {
this.age = age;
this.name = name;
System.out.println("Student(int age, String name)");
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
}
下面是測(cè)試結(jié)果
-----------------序列化----------------------↓
Student(int age, String name)
Student(int age, String name)
Student(int age, String name)
-----------------反序列化----------------------↓
Student [age=10, name=zhao]
Student [age=15, name=kai]
Student [age=20, name=qiang]
因此,我們可以認(rèn)為,在反序列化的時(shí)候,是不需要調(diào)用本類的構(gòu)造函數(shù)的。
2.反序列化的時(shí)候,會(huì)調(diào)用父類的構(gòu)造函數(shù)嗎?
我們新創(chuàng)建1個(gè)Person類,然后用Student繼承自Person,Student的代碼以下
public class Student extends Person implements Serializable {
private int age;
private String name;
public Student() {
System.out.println("Student()");
}
public Student(int age, String name) {
this.age = age;
this.name = name;
System.out.println("Student(int age, String name)");
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
}
Person類的代碼以下
public class Person {
private boolean sex;
public Person() {
System.out.println("Person()");
}
public Person(boolean sex) {
this.sex = sex;
System.out.println("Person(boolean sex)");
}
@Override
public String toString() {
return "Person [sex=" + sex + "]";
}
}
一樣,我把Person的構(gòu)造函數(shù)都進(jìn)行了輸出,然后利用上面的代碼進(jìn)行測(cè)試,下面是測(cè)試結(jié)果
-----------------序列化----------------------↓
Person()
Student(int age, String name)
Person()
Student(int age, String name)
Person()
Student(int age, String name)
-----------------反序列化----------------------↓
Person()
Person()
Person()
Student [age=10, name=zhao]
Student [age=15, name=kai]
Student [age=20, name=qiang]
我們可以看到,雖然Student的構(gòu)造函數(shù)沒有調(diào)用,但是Person的無參構(gòu)造函數(shù)卻調(diào)用了,這也就是說,在反序列化的時(shí)候,本類的構(gòu)造函數(shù)不會(huì)調(diào)用,但是會(huì)調(diào)用其父類的無參構(gòu)造函數(shù)。在沒有繼承的情況下,會(huì)調(diào)用所有類的父類,即Object的構(gòu)造函數(shù)。
3.當(dāng)需要序列化的類的父類沒有實(shí)現(xiàn)序列化的時(shí)候,能否將父類中protect的屬性進(jìn)行序列化和反序列化呢?
為了進(jìn)行測(cè)試,我們需要將Person類的代碼進(jìn)行修改,下面修改以后的代碼
public class Person {
protected boolean sex;
public Person() {
System.out.println("Person()");
}
public Person(boolean sex) {
this.sex = sex;
System.out.println("Person(boolean sex)");
}
@Override
public String toString() {
return "Person [sex=" + sex + "]";
}
}
同時(shí),我們還需要修改Student的toString(),下面是修改以后Student代碼
public class Student extends Person implements Serializable {
private int age;
private String name;
public Student() {
System.out.println("Student()");
}
public Student(int age, String name) {
this.age = age;
this.name = name;
System.out.println("Student(int age, String name)");
}
public Student(int age, String name, boolean sex) {
super(sex);
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + ", sex=" + sex + "]";
}
}
我們進(jìn)行序列化和反序列化,下面是測(cè)試結(jié)果
-----------------序列化----------------------↓
Person(boolean sex)
Person(boolean sex)
Person()
Student(int age, String name)
-----------------反序列化----------------------↓
Person()
Person()
Person()
Student [age=10, name=zhao, sex=false]
Student [age=15, name=kai, sex=false]
Student [age=20, name=qiang, sex=false]
從結(jié)果中可以看到,雖然父類沒有進(jìn)行序列化,但是sex屬性也參與了序列化和反序列化操作,因此不影響。
從上面幾個(gè)測(cè)試的結(jié)果中,我們可以得出結(jié)論:進(jìn)行序列化和反序列化必須調(diào)用其父類的無參的構(gòu)造函數(shù)。
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)