I\O流-序列化与对象输入输出

序列化

序列化指把内存中的Java对象转换成与平台无关的二进制字节序列,以便永久保存在磁盘上或者通过网络进行传输,是Java提供的一种将对象写入到输入流并在之后将其读回的机制。

所以序列化作用有两点:

  1. 便于保存对象信息于磁盘上
  2. 方便对象信息网络传输
  • 序列化:将java对象转换为字节序列
  • 反序列化:把字节序列回复为原先的java对象

序列化的实现

Java提供了对象流ObjectInputStreamObjectOutputStream,可以将以对象形式存在于内存中的数据储存至文件,需要时再将其从文件中读出还原为对象,或者在网络上传送对象。

为了让某个类是可以序列化的,该类可以通过实现Serializable接口,该接口无具体方法,只需声明实现该接口,起到标识性意义,代表该对象是可以序列化的。

下面为一个是实例序列化

import java.io.Serializable;
//首先是序列化的类
public class Person implements Serializable {
    private String name;
    private int age;
    private int id;
    public Person(){}
    public Person (String name,int age,int id){
    this.name = name;
    this.age = age;
    this.id = id;
    }
}

//实现序列化过程
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test {
       public static void main(String[] args) {
             ObjectOutputStream out = null;
              FileOutputStream fos = null;
              try {
                     fos = new FileOutputStream("D:\\ͼƬ\\Tset.txt");
                     out = new ObjectOutputStream(fos);
                     Person p = new Person("张三",45,12);
                     out.writeObject(p);
                     out.flush();
              } catch (IOException e) {
                     throw new RuntimeException(e);
              }finally{
                     try {
                            fos.close();
                            out.close() ;
                     } catch (IOException e) {
                            throw new RuntimeException(e);
                     }
              }

       }

运行成功将Person类对象p保存在磁盘文件Test。txt中
在这里插入图片描述

//反序列化
import java.io.Serializable;

public class Person implements Serializable {
    private String name;
    private int age;
    private int id;
    public Person(){}
    public Person(String name, int age, int id){
    this.name = name;
    this.age = age;
    this.id = id;
    }
    public String toString(){//新添加方法
        return this.name+this.age+this.id;
    }
}


import Work.Person;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Test {
       public static void main(String[] args) {
              ObjectInputStream in = null;
              FileInputStream fis = null;
              try {
                     fis = new FileInputStream("D:\\ͼƬ\\Tset.txt");
                     in = new ObjectInputStream(fis);
                     Person p = (Person)in.readObject();
                     System.out.println(p);

              } catch (Exception e) {
                     throw new RuntimeException(e);
              }finally{
                     try {
                            fis.close();
                            in.close() ;
                     } catch (IOException e) {
                            throw new RuntimeException(e);
                     }
              }
       }
}

按上次序列化生成的Test.txt文件反序列化,由异常出现
Exception in thread “main” java.lang.RuntimeException: java.io.InvalidClassException: Work.Person; local class incompatible: stream classdesc serialVersionUID = 6513129562756671272, local class serialVersionUID = 4654183961547435119
at Work.Test.main(Test.java:24)

serialVersionUID是序列化前后的唯一标识符
默认如果没有人为显式定义过serialVersionUID,那编译器会为它自动声明一个!

因为反序列化,我在Person类中增加了一个String方法,所以serialVersionUID序列化ID前后不一致
serialVersionUID可以看成是序列化和反序列化过程中的“暗号”,在反序列化时,JVM会把字节流中的序列号ID和被序列化类中的序列号ID做比对,只有两者一致,才能重新反序列化,否则就会报异常来终止反序列化的过程。

所以,为了serialVersionUID的确定性,写代码时还是建议,凡是implements Serializable的类,都最好人为显式地为它声明一个serialVersionUID明确值!

public static final long serialVersionUID=475463534532L;
//添加在Person类中

反序列化结果为:
在这里插入图片描述

注意:
transient修饰符的作用了(在实现Serializable接口的情况下
如果在序列化某个类的对象时,就是不希望某个字段被序列化(比如这个字段存放的是隐私值,如:密码等),那这时就可以用transient修饰符来修饰该字段。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值