0
点赞
收藏
分享

微信扫一扫

Java基础知识回顾5-序列化和反序列化

一、概念

Java序列化是指把Java对象转换为字节序列的过程。

Java反序列化是指把字节序列恢复为Java对象的过程。

序列化作用:

在传递和保存对象时,保存对象的完整性和可传递性,对象转换为字节流,可以站网络上传输或者保存在本地文件中。

反序列化作用:

根据字节流中保存的对象状态及描述信息,通过反序列化重建对象。

缺点:

无法跨语言是Java序列化最致命的问题。

对于跨进程的服务调用,服务提供者可能是Java之外的其它语言,当我们需要和其它语言交互时,Java序列化就难以胜任。

二、序列化和反序列化注意事项

1.Java序列化的方式

实现 Serializable 接口:可以自定义 writeObject、readObject、writeReplace、readResolve 方法,会通过反射调用。

实现 Externalizable 接口:需要实现 writeExternal 和 readExternal 方法。

2.序列化ID问题

虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID = 1L)。

3.静态字段不会序列化

序列化时不保存静态变量,这是因为序列化保存的是对象的状态,静态变量属于类的状态,因此序列化并不保存静态变量。

4.transient

如果你不想让对象中的某个成员被序列化可以在定义它的时候加上 transient 关键字进行修饰,这样,在对象被序列化时其就不会被序列化。

transient 修饰过的成员反序列化后将赋予默认值,即 0 或 null。

5.当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化

三、测试

package day01;

import java.io.Serializable;

/**
 * @author qx
 * @date 2023/10/19
 * @des 用户实体类
 */
public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    private Long id;
    private String name;
    // 静态变量不参与序列化
    public static Integer age = 20;
    // transient修饰的变量不参与序列化
    private transient String password;


    public User() {
    }

    public User(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public static Integer getAge() {
        return age;
    }


    @Override
    public String toString() {
        return "User{" + "id=" + id + ", name='" + name + '\'' + ", password='" + password + '\'' + '}';
    }
}

package day01;

import java.io.*;

/**
 * @author qx
 * @date 2023/10/19
 * @des 序列化和反序列化
 */
public class SerializableTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        serializeUser();
        deSerializeUser();
    }

    /**
     * 反序列化
     *
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private static void deSerializeUser() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:" + File.separator + "data.txt"));
        User user = (User) ois.readObject();
        System.out.println(user);
        ois.close();
    }

    /**
     * 序列化
     *
     * @throws IOException
     */
    private static void serializeUser() throws IOException {
        User user = new User();
        user.setId(1L);
        user.setName("qx");
        user.setPassword("123");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:" + File.separator + "data.txt"));
        oos.writeObject(user);
        oos.close();
    }
}

控制台输出:

User{id=1, name='qx', password='null'}


举报

相关推荐

0 条评论