Java基础(6)序列化和反序列化

序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在Java中,这通常意味着将对象转换为字节流,以便可以将其保存到磁盘上或通过网络传输到另一个网络节点。相反,反序列化(Deserialization)是将已序列化的数据恢复为对象的过程。

序列化的基本概念

为了能够序列化,一个类必须实现java.io.Serializable接口。这是一个标记接口(没有方法的接口),用于告知JVM该类的对象可以被序列化。

序列化的过程

序列化过程涉及使用java.io.ObjectOutputStream类。它包装了一个底层的OutputStream,比如FileOutputStream,用于将序列化的对象数据写入文件或其他类型的流。

代码演示:序列化

java 复制代码
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public static void main(String[] args) {
        Student student = new Student("John Doe", 22);
        try (FileOutputStream fileOut = new FileOutputStream("student.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            out.writeObject(student);
            System.out.println("Object has been serialized");
        } catch (IOException i) {
            i.printStackTrace();
        }
    }
}

反序列化的过程

反序列化过程使用java.io.ObjectInputStream类。它包装了一个底层的InputStream,如FileInputStream,用于从文件或其他类型的流中读取并恢复对象数据。

代码演示:反序列化

java 复制代码
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializeStudent {
    public static void main(String[] args) {
        Student student = null;
        try (FileInputStream fileIn = new FileInputStream("student.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            student = (Student) in.readObject();
            System.out.println("Object has been deserialized");
            System.out.println("Name: " + student.name + ", Age: " + student.age);
        } catch (IOException i) {
            i.printStackTrace();
            return;
        } catch (ClassNotFoundException c) {
            System.out.println("Student class not found");
            c.printStackTrace();
            return;
        }
    }
}

序列化中的重要考虑

  • serialVersionUID的角色serialVersionUID是序列化对象的版本标识符。它用于验证序列化对象的发送方和接收方是否加载了与序列化兼容的类。
  • transient关键字 :如果不希望对象的某个属性被序列化,可以使用transient关键字声明这个属性。被transient修饰的属性在序列化过程中会被忽略。
  • 安全性:序列化可能会导致安全问题,因为反序列化时,攻击者可能会修改序列化数据以破坏应用程序的安全性。因此,对于敏感或安全性要求高的数据,需要谨慎使用序列化。

总结

序列化和反序列化是Java编程中处理对象持久化和数据传输的重要技术。通过实现Serializable接口并使用ObjectOutputStreamObjectInputStream,Java类的对象可以轻松地写入到文件或在网络中传输,并可以从中恢复。然而,开发者需要注意序列化的安全性和serialVersionUID等细节,以确保应用程序的正确性和安全性。

相关推荐
Asthenia04121 小时前
为什么说MVCC无法彻底解决幻读的问题?
后端
Asthenia04121 小时前
面试官问我:三级缓存可以解决循环依赖的问题,那两级缓存可以解决Spring的循环依赖问题么?是不是无法解决代理对象的问题?
后端
Asthenia04121 小时前
面试复盘:使用 perf top 和火焰图分析程序 CPU 占用率过高
后端
Asthenia04121 小时前
面试复盘:varchar vs char 以及 InnoDB 表大小的性能分析
后端
Asthenia04121 小时前
面试问题解析:InnoDB中NULL值是如何记录和存储的?
后端
Asthenia04122 小时前
面试官问我:TCP发送到IP存在但端口不存在的报文会发生什么?
后端
Asthenia04122 小时前
HTTP 相比 TCP 的好处是什么?
后端
Asthenia04122 小时前
MySQL count(*) 哪个存储引擎更快?为什么 MyISAM 更快?
后端
Asthenia04122 小时前
面试官问我:UDP发送到IP存在但端口不存在的报文会发生什么?
后端
Asthenia04122 小时前
深入理解 TCP backlog 参数:意义、应用场景与 Netty 中的应用
后端