JavaWeb~对象的序列化与反序列化

什么是序列化与反序列化

  • 序列化
    序列化就是将一个对象变成二进制的比特流 可以把这个比特流保存到文件中 或者通过网络传输
  • 反序列化
    将序列化后的二进制比特流还原回原来的对象
  • 简单来说就好比我们看大科幻电影 里面有很多的情节是这样的 将一个人或者物体变成一串数字和字母流 然后传送到很远的地方再将这一串数字和字母流变回原来的物体 这一过程和序列化反序列化很像 将物体变成数字字母流就是序列化 将数字字母流变成物体就是反序列化

为什么需要序列化?

  1. 当我们需要把内存中的对象状态保存到一个文件中或者数据库中时候
  2. 用套接字在网络上传送对象的时候
  3. 序列化最大的目的就是为了能让对象通过网络传输 能够保存在文件中 防止丢失找不到

实现Java对象的序列化与反序列化

  • 要注意几点
  1. 如果对象要进行序列化需要实现Serializable接口
  2. ObjectOutputStream 用于序列化
  3. ObjectInputStream 用于反序列化
  4. transient修饰的变量不可以序列化
  5. static 修饰的变量不能被序列化
import java.io.*;

//实现serializable接口才可以实现对象的序列化
class Person implements Serializable {
    public String name;
    public int age;
    public String sex;
    //transient修饰的变量不可以序列化
    transient public String cardId;
    //static 修饰的变量不能被序列化
    public static String phoneNum;

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

    public static void setPhoneNum(String phoneNum) {
        Person.phoneNum = phoneNum;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", cardId='" + cardId + '\'' +
                ", phoneNum='" + phoneNum + '\'' +
                '}';
    }
}
public class SerializTest {

    public static void main(String[] args) {

        Person person = new Person("Listen", 21, "MAN", "100100100111");
        Person.setPhoneNum("120");

        //序列化一个对象
        serializPreson(person);

        //反序列化一个对象
        Person personRet = desSerializable();
        System.out.println(personRet);


    }

    private static Person desSerializable() {

        Person person = null;

        try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\java\\java.txt"))){

            person = (Person) objectInputStream.readObject();
            System.out.println("反序列化成功");

        } catch (IOException | ClassNotFoundException e) {
            e.getStackTrace();
        }

        return person;
    }

    private static void serializPreson(Person person) {

        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\java\\java.txt"))){

            //将person对象序列化输入文件
            // 这个 writeObject 集序列化+写文件 两者同时搞定
            objectOutputStream.writeObject(person);
            System.out.println("序列化成功");

        } catch (IOException e) {
            e.getStackTrace();
        }
    }
}

  • 运行结果
    在这里插入图片描述
  • 我们可以看到cardId被transient修饰不能被序列化 所以得到的反序列化结果他的值就是null 但是我们说被static修饰的phoneNum也不能序列化 但是此处它尽然不显示null 这是因为 他是静态变量 在代码编译期间就已经存储在方法区的 所以他不需要序列化也可以获得值

关于serialVersionUID 的问题

  • 如果序列化程序和反序列化程序不是用一个程序 然后俩个程序中都有一个Person类他们之间只有名字相同个别属性是不相同的 这时就会出现问题
  • 这时就需要使用serialVersionUID 变量的值 这个变量无需手动设置(也可以手动设置但是不推荐) 编译器在编译的时候就会自动生成这个值(根据类的内容生成) 类的代码出现变化的时候 生成的这个uid值差距是很大的 所以在反序列化的时候 就可以检查这个uid的值 是否符合预期 就能判断当前类的代码是否一致
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值