Java序列化面试

Java序列化

序列化是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

序列化的作用

  • 持久化对象及其状态到内存或者磁盘

Java 平台允许我们在内存中创建可复用的 Java 对象,但一般情况下,只有当 JVM 处于运行时,这些对象才可能存在,即这些对象的生命周期不会比 JVM 的生命周期更长。 但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java 对象序列化可以实现该功能。

  • 序列化用户远程对象传输

除了在持久化对象时会用到对象序列化之外,当使用 RMI(远程方法调用,前段时间的log4j2的漏洞就是通过rmi),或在网络中传递对象时,都会用到对象序列化。 Java序列化API 为处理对象序列化提供了一个标准机制。

Serializable实现序列化

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

废话不多说,上个Demo给大家乐呵乐呵。

public class User implements Serializable {

    private static final long serialVersionUID = 1619078257311L;

    private String name;
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
    public static void main(String[] args) throws Exception{
        OutputStream os = new FileOutputStream("/Users/jerry/Desktop/User.txt");
        ObjectOutputStream ops = new ObjectOutputStream(os);
        User user = new User("Jerry",18);
        ops.writeObject(user);
        ops.close();
        System.out.println("开始序列化-----" + user); 

        InputStream is = new FileInputStream("/Users/jerry/Desktop/User.txt");
        ObjectInputStream ips = new ObjectInputStream(is);
        User users = (User)ips.readObject();
        ips.close();
        System.out.println("反序列化------"+users);
    }

}

控制台输出:
在这里插入图片描述
文件内容:
在这里插入图片描述
乱码是因为我们在保存的时候是通过二进制写入进行保存的,所以属于正常现象。

当我们在使用 Java 对象序列化时,会把其状态保存为一组字节,之后再将这些字节组装成对象。需要注意的是,在对象序列化时保存的是对象的”状态”,即它的成员变量。因此对象序列化不会关注类中的静态变量,所以静态变量不会被序列化

序列化ID

细心的人会发现在刚才的User类中有一个serialVersionUID字段,该字段的作用是在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类,当序列化ID不一致时,会抛出InvalidClassException错误。
在这里插入图片描述

transient关键字防止序列化

对于一些敏感的字段,比如密码,当不希望该字段进行序列化时,可以使用transient关键字来防止序列化。

transient private Integer age;

此时的age字段就没有被序列化。
在这里插入图片描述

最后需要注意的一点是当类中有其它类作为字段的时候,如果该引用类没有实现序列化Serializable接口的话,那么在序列化的时候就会抛出NotSerializableException错误。
在这里插入图片描述

好的。

我说完了。

你也看完了。

真棒。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值