当前位置: 首页 > article >正文

【Java序列化】使用Java 自带的Serializer进行对象序列化和反序列化

在Java开发中,对象序列化和反序列化是常见的需求。序列化是指将对象的状态转换为字节流,从而可以将其存储到文件中或通过网络进行传输。反序列化则是这个过程的逆操作,即将字节流重新转换为对象。Java标准库提供了ObjectOutputStreamObjectInputStream类来实现这些功能。本文将介绍如何使用这些类来实现一个简单的序列化工具类JdkSerializer

JdkSerializer类的实现

首先,我们需要创建一个实现了Serializable接口的类JdkSerializer。这个接口是一个标记接口,用于指示某个类的对象可以被序列化。虽然JdkSerializer类本身不需要直接实现任何方法,但实现这个接口是序列化类的标准做法。

以下是JdkSerializer类的实现:

import java.io.*;  
  
public class JdkSerializer implements Serializable {  
  
    // 序列化方法  
    public <T> byte[] serialize(T obj) throws IOException {  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);  
        objectOutputStream.writeObject(obj);  
        objectOutputStream.close();  
        return out.toByteArray();  
    }  
  
    // 反序列化方法  
    public <T> T deserialize(byte[] bytes) throws IOException {  
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);  
        ObjectInputStream objectInputStream = new ObjectInputStream(in);  
        try {  
            return (T)objectInputStream.readObject();  
        } catch(ClassNotFoundException e) {  
            throw new RuntimeException(e);  
        } finally {  
            objectInputStream.close();  
        }  
    }  
}

序列化方法

serialize方法接收一个泛型对象T作为参数,并返回一个字节数组。这个方法的实现步骤如下:

  1. 创建一个ByteArrayOutputStream实例,用于存储序列化后的字节流。
  2. 创建一个ObjectOutputStream实例,并将其包装在ByteArrayOutputStream中。
  3. 调用writeObject方法将对象序列化并写入到ByteArrayOutputStream中。
  4. 关闭ObjectOutputStream(注意:在实际应用中,应该使用try-with-resources语句来自动关闭流,这里为了简洁起见省略了)。
  5. 返回ByteArrayOutputStream中的字节数组。

反序列化方法

deserialize方法接收一个字节数组作为参数,并返回一个泛型对象T。这个方法的实现步骤如下:

  1. 创建一个ByteArrayInputStream实例,并将字节数组作为输入。
  2. 创建一个ObjectInputStream实例,并将其包装在ByteArrayInputStream中。
  3. 调用readObject方法从ObjectInputStream中读取对象,并将其转换为泛型类型T
  4. 捕获ClassNotFoundException异常,并将其包装为一个RuntimeException抛出。这是因为如果在反序列化过程中找不到对象的类定义,则无法正确创建对象。
  5. finally块中关闭ObjectInputStream

使用示例

以下是一个简单的使用示例,展示了如何使用JdkSerializer类来序列化和反序列化一个对象:

public class Main {  
    public static void main(String[] args) {  
        try {  
            JdkSerializer serializer = new JdkSerializer();  
  
            // 创建一个对象  
            Person person = new Person("Alice", 30);  
  
            // 序列化对象  
            byte[] serializedPerson = serializer.serialize(person);  
            System.out.println("Serialized Person: " + Arrays.toString(serializedPerson));  
  
            // 反序列化对象  
            Person deserializedPerson = serializer.deserialize(serializedPerson);  
            System.out.println("Deserialized Person: " + deserializedPerson);  
  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}  
  
class Person implements Serializable {  
    private String name;  
    private int age;  
  
    public Person(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
  
    @Override  
    public String toString() {  
        return "Person{name='" + name + "', age=" + age + "}";  
    }  
}

 

在这个示例中,我们定义了一个Person类,并实现了Serializable接口。然后,我们使用JdkSerializer类来序列化和反序列化一个Person对象。

注意事项

  1. 安全性:序列化和反序列化过程可能会引发安全问题,因为反序列化过程中会执行字节流中的代码。因此,在反序列化不可信的数据时,需要特别注意安全性。
  2. 版本兼容性:在序列化和反序列化过程中,对象的类定义必须保持一致。如果类的定义发生了变化(例如,添加或删除了字段),则可能会导致反序列化失败或数据不一致。
  3. 性能:序列化和反序列化过程可能会消耗较多的时间和资源,特别是在处理大型对象或复杂对象图时。因此,在性能敏感的场景中,需要谨慎使用。

通过本文的介绍,你应该已经了解了如何使用Java标准库中的ObjectOutputStreamObjectInputStream类来实现一个简单的序列化工具类JdkSerializer。希望这个工具类能够帮助你在实际开发中更加高效地处理对象的序列化和反序列化。


http://www.kler.cn/news/331367.html

相关文章:

  • 2024年OpenAI DevDay发布实时 API、提示缓存等新功能
  • 软考系统分析师知识点一:绪论
  • Ubuntu20.04如何安装Microsoft Edge浏览器?
  • Linux云计算 |【第四阶段】RDBMS1-DAY5
  • ATLAS/ICESat-2 L3B 每 3 个月网格动态海洋地形图 V001
  • 算法【Java】—— 递归
  • centos环境安装JDK详细教程
  • 在Docker中运行微服务注册中心Eureka
  • 复习HTML(进阶)
  • eNSP网络配置指南:IP设置、DNS、Telnet、DHCP与路由表管理
  • 1.2.2 计算机网络的分层结构(下)
  • 【转载翻译】消息队列 - ActiveMQ、RabbitMQ、Kafka、ZeroMQ
  • 玄派玄机星16N:240Hz高刷战场,185W性能怪兽来袭
  • ElasticSearch备考 -- Search scroll
  • Python selenium库学习使用实操
  • (done) 声音信号处理基础知识(11) (Complex Numbers for Audio Signal Processing)
  • WindowsTerminal中oh-my-posh样式的cmd、git-bash、cmder配置参数
  • CSS实现文本超出隐藏并显示省略号
  • 【SpringBoot】基础+JSR303数据校验
  • 原生 JS 操作 DOM 元素