首页 > 代码库 > java中序列化与反序列化的冷知识

java中序列化与反序列化的冷知识

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992

    关于什么是序列化,和为什么要序列化的知识就不再阐述了,本文主要探讨一些特殊点的情况。

    

    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.反序列化的时候,会调用父类的构造函数吗?

    我们新创建一个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属性也参与了序列化和反序列化操作,因此不影响。


    从上面几个测试的结果中,我们可以得出结论:进行序列化和反序列化必须调用其父类的无参的构造函数。







java中序列化与反序列化的冷知识