程序员人生 网站导航

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

栏目:综合技术时间:2015-01-06 08:55:34

    转载请注明出处: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属性也参与了序列化和反序列化操作,因此不影响。


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







------分隔线----------------------------
------分隔线----------------------------

最新技术推荐