首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用java.io库序列化Java对象

使用java.io库序列化Java对象

作者头像
方亮
发布2024-05-24 19:19:07
发布2024-05-24 19:19:07
2410
举报
文章被收录于专栏:方亮方亮
大纲

  • Json方案
  • 二进制方案
    • 核心代码
    • 测试代码
      • 数据类
      • Pom.xml
      • 测试代码
        • 基础类型
        • 数组
        • List
        • Set
        • Map
  • 文件方案
    • 核心代码
  • 代码

在我们使用诸如Redis这类缓存系统时,我们往往会存在如下需求:将Java对象保存到Redis缓存中,然后在其他机器上还原回来。

Json方案

我们可以引入Json库等方式,将Java对象序列化为Json字符串来实现这个目的,但是这样的方案还是过于复杂。因为对于二进制类型数据,我们需要通过Base64之类的字符转换方式将其变成Json可以存储的字符串类型。反序列化时,又要Base64反解。这过程非常繁琐而且严重影响整体的效率。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二进制方案

实际我们可以使用java.io库中相关类,直接将Java对象转换为二进制;还可以直接通过加载二进制数据重新构建该对象。并且这个操作支持数组、List、Set、Map等非基础类型

在这里插入图片描述
在这里插入图片描述

直接上代码

核心代码

代码语言:javascript
复制
package org.serialize.serializer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class MemorySerialize {
    public static <T> byte[] serialize(T obj) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
            oos.writeObject(obj);
            return bos.toByteArray();
        }
    }

    public static <T> T deserialize(byte[] data) throws Exception {
        ByteArrayInputStream bis = new ByteArrayInputStream(data);
        try( ObjectInputStream ois = new ObjectInputStream(bis)) {
            @SuppressWarnings("unchecked")
            T obj = (T) ois.readObject();  
            return obj;
        }
    }
}

测试代码

数据类

下面的数据类包含了8种Java基础类型。 为了书写方便,我们使用了Data注解来帮我们生成诸如set/get类操作。 数据类需要继承于java.io.Serializable接口,否则生成操作会报错。

代码语言:javascript
复制
package org.serialize.pojo;

import lombok.Data;

@Data
public class BaseTypes implements java.io.Serializable{
    private byte byteValue;
    private short shortValue;
    private int intValue;
    private long longValue;
    private float floatValue;
    private double doubleValue;
    private char charValue;
    private boolean booleanValue;
}
Pom.xml

因为引入了lombok,并且需要写单元测试,所以在pom.xml中新增如下依赖。

代码语言:javascript
复制
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
测试代码
基础类型
代码语言:javascript
复制
    @Test
    public void testSerializeBaseTypes() {
        BaseTypes baseTypes = new BaseTypes();
        baseTypes.setByteValue((byte) 1);
        baseTypes.setShortValue((short) 2);
        baseTypes.setIntValue(3);
        baseTypes.setLongValue(4L);
        baseTypes.setFloatValue(5.0f);
        baseTypes.setDoubleValue(6.0);
        baseTypes.setCharValue('7');
        baseTypes.setBooleanValue(true);

        try {
            byte[] data = MemorySerialize.serialize(baseTypes);
            BaseTypes baseTypesDeserialized = MemorySerialize.deserialize(data);
            assertEquals(baseTypes, baseTypesDeserialized);
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }
数组
代码语言:javascript
复制
@Test
    public void testSerializeBaseTypesArray() {
        BaseTypes[] baseTypesArray = new BaseTypes[3];
        for (int i = 0; i < baseTypesArray.length; i++) {
            BaseTypes baseTypes = new BaseTypes();
            baseTypes.setByteValue((byte) (i + 1));
            baseTypes.setShortValue((short) (i + 2));
            baseTypes.setIntValue(i + 3);
            baseTypes.setLongValue(i + 4L);
            baseTypes.setFloatValue(i + 5.0f);
            baseTypes.setDoubleValue(i + 6.0);
            baseTypes.setCharValue((char) (i + 7));
            baseTypes.setBooleanValue(i % 2 == 0);
            baseTypesArray[i] = baseTypes;
        }

        try {
            byte[] data = MemorySerialize.serialize(baseTypesArray);
            BaseTypes[] baseTypesArrayDeserialized = MemorySerialize.deserialize(data);
            assertArrayEquals(baseTypesArray, baseTypesArrayDeserialized);
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }
List
代码语言:javascript
复制
    @Test
    public void testSerializeBaseTypesWithArrayList() {
        List<BaseTypes> baseTypesArrayList = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            BaseTypes baseTypes = new BaseTypes();
            baseTypes.setByteValue((byte) (i + 1));
            baseTypes.setShortValue((short) (i + 2));
            baseTypes.setIntValue(i + 3);
            baseTypes.setLongValue(i + 4L);
            baseTypes.setFloatValue(i + 5.0f);
            baseTypes.setDoubleValue(i + 6.0);
            baseTypes.setCharValue((char) (i + 7));
            baseTypes.setBooleanValue(i % 2 == 0);
            baseTypesArrayList.add(baseTypes);
        }

        try {
            byte[] data = MemorySerialize.serialize(baseTypesArrayList);
            List<BaseTypes> baseTypesArrayListDeserialized = MemorySerialize.deserialize(data);
            assertEquals(baseTypesArrayList, baseTypesArrayListDeserialized);
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }
Set
代码语言:javascript
复制
    @Test
    public void testSerializeBaseTypesWithSet() {
        Set<BaseTypes> baseTypesSet = new HashSet<>();
        for (int i = 0; i < 3; i++) {
            BaseTypes baseTypes = new BaseTypes();
            baseTypes.setByteValue((byte) (i + 1));
            baseTypes.setShortValue((short) (i + 2));
            baseTypes.setIntValue(i + 3);
            baseTypes.setLongValue(i + 4L);
            baseTypes.setFloatValue(i + 5.0f);
            baseTypes.setDoubleValue(i + 6.0);
            baseTypes.setCharValue((char) (i + 7));
            baseTypes.setBooleanValue(i % 2 == 0);
            baseTypesSet.add(baseTypes);
        }
        
        try {
            byte[] data = MemorySerialize.serialize(baseTypesSet);
            Set<BaseTypes> baseTypesSetDeserialized = MemorySerialize.deserialize(data);
            assertEquals(baseTypesSet, baseTypesSetDeserialized);
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }
Map
代码语言:javascript
复制
    @Test
    public void testSerializeBaseTypesWithMap() {
        Map<String, BaseTypes> baseTypesMap = new HashMap<>();
        for (int i = 0; i < 3; i++) {
            BaseTypes baseTypes = new BaseTypes();
            baseTypes.setByteValue((byte) (i + 1));
            baseTypes.setShortValue((short) (i + 2));
            baseTypes.setIntValue(i + 3);
            baseTypes.setLongValue(i + 4L);
            baseTypes.setFloatValue(i + 5.0f);
            baseTypes.setDoubleValue(i + 6.0);
            baseTypes.setCharValue((char) (i + 7));
            baseTypes.setBooleanValue(i % 2 == 0);
            baseTypesMap.put(String.valueOf(i), baseTypes);
        }

        try {
            byte[] data = MemorySerialize.serialize(baseTypesMap);
            Map<String, BaseTypes> baseTypesMapDeserialized = MemorySerialize.deserialize(data);
            assertEquals(baseTypesMap, baseTypesMapDeserialized);
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

文件方案

将Java对象直接保存到文件中,以及直接从文件中加载内容并转换为Java对象,可以使用java.io库中FileInputStream、FileOutputStream来实现。

在这里插入图片描述
在这里插入图片描述

核心代码

代码语言:javascript
复制
package org.serialize.serializer;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class FileSerialize {
    public static <T> void serialize(T obj, String fileName) throws Exception {
        try(FileOutputStream fos = new FileOutputStream(fileName)) {
            try(ObjectOutputStream oos = new ObjectOutputStream(fos)) {
                oos.writeObject(obj);
                oos.flush();
            }
        }
    }

    public static <T> T deserialize(String fileName) throws Exception {
        try (FileInputStream fis = new FileInputStream(fileName)) {
            try (ObjectInputStream ois = new ObjectInputStream(fis)) {
                @SuppressWarnings("unchecked")
                T obj = (T) ois.readObject();
                return obj;
            }
        }
    }

}

代码

完整代码 https://github.com/f304646673/JavaUtils/tree/master/src/main/java/org/serialize

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大纲
  • Json方案
  • 二进制方案
    • 核心代码
    • 测试代码
      • 数据类
      • Pom.xml
      • 测试代码
  • 文件方案
    • 核心代码
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档