java序列化和反序列化

java序列化和反序列化


一、什么是序列化和反序列化

序列化:将对象转化成一个字节序列(二进制数据)的过程。
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化。

反序列化:将一个对象的字节序列恢复成 Java 对象的过程。

一个平台中序列化的对象,可以在另一个平台中进行反序列化,因为这个过程是在 JVM 中独立完成的,可以依赖于 Java 的可移植性。

二、序列化的作用

1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。


三、序列化

首先创建一个测试类:包含了变量和方法;
一个类要想被序列化必须继承Serializable接口;

测试类

package serialization;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;

public class Demo1 implements Serializable {
    public String name;
//    protected transient int age;        //不参与序列化
//    private static final long serialVersionUID=42;      //不能反序列化

    public Demo1(){
        this.name="rabbit";
    }
    public void exec() throws IOException {
        Process process = Runtime.getRuntime().exec("whoami");
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line=bufferedReader.readLine())!=null){
            System.out.println(line);
        }
    }
}

序列化类

package test;

import serialization.Demo1;

import java.io.*;

public class Serialization {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Demo1 demo1 = new Demo1();
        //正常的操作
        System.out.println(demo1.name);
        demo1.exec();
//        序列化操作
        ObjectOutputStream serialize = new ObjectOutputStream(new FileOutputStream("src\\main\\java\\serialization\\serialize"));
        serialize.writeObject(demo1);
        serialize.close();
    }
}

会生成一个serialize文件即测试类序列化后的字符:
在这里插入图片描述

四、反序列化

将上述序列化后的文件进行反序列化

package test;

import serialization.Demo1;

import java.io.*;

public class Serialization {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Demo1 demo1 = new Demo1();
        //正常的操作
        System.out.println(demo1.name);
        demo1.exec();

        //反序列化操作
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("src\\main\\java\\serialization\\serialize"));
        Demo1 o = (Demo1) objectInputStream.readObject();
        o.exec();
        System.out.println(o.name);

    }
}

执行结果
在这里插入图片描述

五、总结

1、核心类与关键字总览

ObjectOutputStream:IO 类,包含序列化对象的方法,writeObject()

ObjectInputStream:IO 类,包含反序列化对象的方法,readObject()

上面两个 IO 流类是高层次的数据库,需要借助文件流进行序列化与反序列化操作。

serializable:接口,是一个标志性接口,标识可以在 JVM 中进行序列化,JVM 会为该类自动生成一个序列化版本号。参与序列化与反序列化的类必须实现 Serializable 接口。

serialVersionUID:类属性,序列化版本号,用于给 JVM 区别同名类,没有提供版本号,JVM会默认提供序列化版本号。

transient:关键字,当序列化时,不希望某些属性参与,则可以使用这个关键字标注该属性。

2、注意

private static final long serialVersionUID=42; //不能反序列化

1、当父类继承Serializable接口时,所有子类都可以被序列化

2、子类实现了Serializable接口,父类没有,父类中的属性不能序列化(不报错,数据丢失),但是在子类中属性仍能正确序列化

3、如果序列化的属性是对象,则这个对象也必须实现Serializable接口,否则会报错

4、反序列化时,如果对象的属性有修改或删减,则修改的部分属性会丢失,但不会报错

5、反序列化时,如果serialVersionUID被修改(默认值是42),则反序列化时会失败,
例:private static final long serialVersionUID=40; //不能反序列化

6、protected transient int age; 表示age变量不参与序列化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值