序列化与反序列化详解

1.序列化基本概念

1.1对象序列化

对象序列化指的是,将内存中保存的对象变为二进制数据流的形式进行传输,或者将其保存在文本中(反序列化与序列化相反,实现对象持久化,即外部序列化)。但是并不是所有类的对象都可以被序列化,严格来说,需要被序列化的类的对象往往需要传输使用,同时这个类必须实现java.io.Serializable 接口 (Externalizable需要手动保存,很少用)),才具备对象序列化的功能。这个接口并莫有任何方法,它只是个标识而已。序列化对象时所需要保存的就是对象中的属性,所以默认情况下对象的属性将被转化为二进制数据流存在。

1.2对象序列化的特点

  • 如果一个类能被序列化,那么它的子类也可以被序列化
  • static代表的类成员,transient代表对象的临时数据,这两种数据成员是不能够被序列化的

2.对象序列化与对象反序列化

2.1序列化

在Java.io包中提供处理类:ObjectOutputStream(将对象转成二进制形式),ObjectOutput(不常用)

public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants
public ObjectOutputStream(OutputStream out)throws IoException
WriteObject(Object obj)//将obj变为二进制流输出到目标终端

2.2反序列化

在Java.io包中提供处理类:ObjectInputStream(将二进制转化为对象),ObjectInput(不常用)

public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants
public ObjectInputStream(InputStream in) throws IoException 
readObject()  选择反序列化的目标终端

2.3序列化与反序列化示例

class Person implements Serializable{
    private  transient String name;
    private int age;
    public Person(String name, int age) {
        super();

        this.name = name;
        this.age = age;
    }
    @Override
    public String toString(){
        return "person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class TestSerializable {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化
        Person per=new Person("马云",35);
        OutputStream outputStream=new FileOutputStream(new File(
                "C:\\Users\\QLH\\Desktop\\aaa.txt"));
        ObjectOutputStream out= new ObjectOutputStream(outputStream);
        out.writeObject(per);
        outputStream.close();
        out.close();


//反序列化
      InputStream inputStream=new FileInputStream(new File(
                "C:\\Users\\QLH\\Desktop\\aaa.txt"));
      ObjectInputStream in=new ObjectInputStream(inputStream);
      Person person=(Person) in.readObject();
      System.out.println(person );

    }
}

2.3.序列化的使用场景

由于序列化的使用会影响系统的性能,因此如果不是必须使用序列化,应尽可能的不要使用序列化,序列化的使用场景如下:

  • 需要通过网络发送对象,或该对象的状态需要被持久化到数据库或文件中
  • 序列化能实现深复制,即可复制引用的对象(深浅拷贝

2.4反序列化与序列化主要区别

序列化是内置API,只需要实现serializable接口,开发人员不需要编写任何代码就可以实现对象的序列化,反序列化使用时,Externalizable接口中的读写方法必须由开发人员来实现。因此与实现serializable接口的方法相比,使用Externalizable编写程序的难度更大 ,但是在编程时把控制权交给开发后,使得编程更灵活,对需要持久化的那些属性可以进行控制,性能会提高。

3.部分属性序列化

3.1在接口中使用Serializable

在用接口Serializable接口时,若希望类中的若干属性不被序列化保存(serializable默认会将所有属性序列化保存),可以在属性前添加Transient关键字。transient关键字的作用:阻止实例中那些用此关键字修饰的变量序列化。当对象被反序列化时,被transient修饰的变量值不会被持久化和恢复。transient只能修饰变量,不能修饰类和方法。

3.2使用Externalizable

开发人员可根据实现需求来实现readExternal与writeExternal方法来控制序列化与反序列化所使用的的属性,这种方法的缺点是增加了编程的难度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值