java中序列化与反序列化的冷知识
来源:程序员人生 发布时间:2015-01-06 08:55:34 阅读次数:2321次
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992
关于甚么是序列化,和为何要序列化的知识就不再论述了,本文主要探讨1些特殊点的情况。
1.java中如何实现序列化和反序列化
下面的代码是进行序列化的简单实例
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.在反序列化的时候,需要调用本类的构造函数吗? 我的测试序列化的类以下,在无参和有参的构造函数中,打印了语句,然后,我们使用上面的序列化和反序列化代码进行测试。
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 + "]";
}
}
下面是测试结果
-----------------序列化----------------------↓
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]
因此,我们可以认为,在反序列化的时候,是不需要调用本类的构造函数的。
2.反序列化的时候,会调用父类的构造函数吗?
我们新创建1个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的构造函数都进行了输出,然后利用上面的代码进行测试,下面是测试结果
-----------------序列化----------------------↓
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的构造函数没有调用,但是Person的无参构造函数却调用了,这也就是说,在反序列化的时候,本类的构造函数不会调用,但是会调用其父类的无参构造函数。在没有继承的情况下,会调用所有类的父类,即Object的构造函数。
3.当需要序列化的类的父类没有实现序列化的时候,能否将父类中protect的属性进行序列化和反序列化呢?
为了进行测试,我们需要将Person类的代码进行修改,下面修改以后的代码
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 + "]";
}
}
同时,我们还需要修改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 + "]";
}
}
我们进行序列化和反序列化,下面是测试结果
-----------------序列化----------------------↓
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]
从结果中可以看到,虽然父类没有进行序列化,但是sex属性也参与了序列化和反序列化操作,因此不影响。
从上面几个测试的结果中,我们可以得出结论:进行序列化和反序列化必须调用其父类的无参的构造函数。
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠