序列化和反序列化的详解

1.为什么需要 Java 序列化(Serialization)?

Java 提供了一种对象序列化和反序列化的机制。 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。

序列化的流叫做序列化流持久化对象);反序列化的流叫做反序列化流重构对象)。

可以对流化后的对象进行 读 写 操作,也可将流化后的对象传输于网络之间

简而言之,对象序列化是将对象状态转换为可保持或传输的格式过程。

序列化是为了解决在对对象流进行读写操作时所引发的问题

2.如何实现 Java 序列化(Serialization)?

将 需 要 被 序 列 化 的 类 实 现 Serializable 接 口 , 该 接 口 没 有 需 要 实 现 的 方 法 , implements Serializable 只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造 一个 ObjectOutputStream(对象流)对象,接着,使用 ObjectOutputStream 对象的 writeObject(Object obj)方法就 可以将参数为 obj 的对象写出(即保存其状态),要恢复的话则用输入流。

3.Java 序列化中,如果有些字段不想进行序列化怎么办?

        对于不想进行序列化的变量,使用 transient 关键字修饰

当对象被序列化时,阻止实例中那些用此关键字修饰的的变量序列化。

当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。

transient 只能修饰变量,不能修饰类和方法。

4.序列化 和 反序列化 作用

        序列化:主要用于网络传输,数据持久化,一般序列化也称为编码(Encode)。

        反序列化:主要用于从网络或磁盘上读取字节数组还原成原始对象,一般反序列化也称为解码(Decode)。

序列化 和 反序列化作用

        1.数据持久化:简而言之,就是将数据存储到磁盘文件的时候,需要将对象序列化存入磁盘中。

        2.网络传输中:当分布式系统中需要传输同一个对象时,就用到序列化与反序列化。将传输的对象序列化传输到另一个系统中,另一个系统读取的时候通过将字节序列转换为对象读取出来

序列化,是指把Java对象转换为字节序列的过程(持久化对象

java.io.ObjectOutputStream类继承OutputStream,

是一个字节输出流,可以用来写出字节数据,并且可以写对象。

序列化的注意事项:
    1被序列化的对象所属的类一定要实现Serializable接口(标记接口)
    2被序列化的对象所有的属性也是要可以被序列化的
    3如果别的序列化的对象的属性不想被序列化,那么该属性就需要使用transient关键字修饰,表示瞬态

public class Person implements Serializable {
    static final long serialVersionUID=21L;//序列化版本号

    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
//序列化
public class Test01 {
    public static void main(String[] args) throws Exception{
        // 1.创建Person对象
        Person p = new Person("张三",18);

        // 2.创建序列化流对象,关联目的地文件路径
        FileOutputStream fos = new FileOutputStream("day01\\aa\\a.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        // 3.序列化对象
        oos.writeObject(p);

        // 4.关闭流,释放资源
        oos.close();
    }
}

反序列化,是指把字节序列恢复为Java对象的过程(重建对象

java.io.ObjectInputStream类继承InputStream,

是一个字节输入流,可以用来读字节数据,并且可以读对象。

反序列化的注意事项:
    1如果找不到class文件,反序列化会失败,抛出一个classNotFoundException异常incompatible
    2.如果能找到该类的class文件,但序列化后又修改了类,会导致反序列化失败,抛出一个InvalidClassException异常


解决InvalidClassException异常的反序列化方法:

        增加序列化版本号:static final long serialVersionUID=21L

//反序列化
public class Test02 {
    public static void main(String[] args) throws Exception{
        // 1.创建反序列化流对象,关联数据源文件路径
        FileInputStream fis = new FileInputStream("day01\\aa\\a.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);

        // 2.重构对象
        Object obj = ois.readObject();

        // 3.关闭流,释放资源
        ois.close();

        // 4.打印对象
        System.out.println(obj.toString());
    }
}

序列化和反序列化注意:

声明为static和transient类型的数据不能被序列化,反序列化需要一个无参构造函数。

在 Java 中能够被序列化的类必须先实现 Serializable 接口,该接口没有任何抽象方法只是起到一个标记作用。

Json/xml的数据传递

在数据传输(也称为网络传输)前,先通过序列化工具类将Java对象序列化为Json/xml文件。

在数据传输(也称为网络传输)后,再将Json/xml文件反序列化为对应语言的对象。

序列化版本号(serialVersionUID)

s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D​:​ ​字​面​意​思​上​是​序​列​化​的​版​本​号​,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。

序列化版本号(serialVersionUID)的作用

        当实现了Serializable的类(没有定义序列化版本号)序列化成功后进行了修改,当对这个类的实例对象进行反序列化时就会报错,因为这个对象的序列化版本号在类修改之后和之前的对应不上了(安全机制)。

解决InvalidClassException异常的反序列化方法(解决办法:增加序列化版本号):

        在定义这个类时就指定一个序列化版本号,这样编译器就不会自动为其设置版本号。

//serialVersionUID = 可以为“任意数值”+L,但不能重复
private static final long serialVersionUID = 1L;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值