对象序列化

来源:互联网 发布:js 多条件判断 编辑:程序博客网 时间:2024/05/02 00:14

对象序列化

对象序列化的目标是将对象保存在磁盘中或者允许其在网络中直接传输对象。对象序列化机制会将内存中的Java对象转化为与平台无关的二进制流。其他程序可以通过该二进制流恢复成原来的Java对象

要使对象能够序列化就必须实现下面两个接口中的一个

  • Serializable
  • Externalizable

Serializable是一种标记型借口,没有实现方法,但是缺少该接口对象将无法完成序列化

例:

首先创建类并实现Serializable接口

public class test implements java.io.Serializable{    public int age;    public test(int a){        age=a;    }}

通过ObjectOutputStream将其写入磁盘文件

public static void main(String args[]){    //使用try catch抛出异常的同时在结束时释放资源    try(ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.txt"))){//object.txt是存放二进制流的文件    test t=new test(10);    oos.writeObject(t);    }catch(IOException){        ex.printStackTrace();    }}

使用ObjectInputStream将其转换为Java类

public static void main(String args[]){    try(    ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.txt"))){    test a=(test)ois.readObject();    System.out.println(a.age);    }}

注:反序列化无需通过构造器创建对象

对象引用的序列化

如果一个对象中创建了其他对象,那么程序在序列化该对象时会先将它的引用对象序列化,因此对象在序列化时其引用变量也必须被序列化。

重复序列化问题

现有如下情况

//设有一个类TEST的构造器以test类为参数test t=new test(10);TEST a=new TEST(t);TEST b=new TEST(t);

在这种情况下如果引用t的时候都进行一次序列化,那么a和b所引用的参数将会是两个对象,而我们的原意是使它们引用同一个test t。所以Java在设计序列化时规定

  • 所有保存到磁盘中的对象都有一个序列化编号。
  • 当程序试图将一个对象序列化时会先检查该对象是否已经被序列化过
  • 如果对象已经被序列化过,程序将知识输出一个序列化编号。

注:这个方式有一个问题就是如果对同一个对象只执行一次序列化,那么如果该对象中途发生改变时会导致其变化不会被记录。比如

test t=new test(10);TEST a=new TEST(t);test t=new test(9);TEST b=new TEST(t);

对t的改变没有意义,因为程序只进行一次序列化,之后的t只会输出一个序列化编号引用第一次序列化的二进制流

0 0