【Java从入门到放弃 之 应用反射实现简单的序列化与反序列化】

应用反射实现简单的序列化与反序列化

应用反射实现简单的序列化与反序列化

反射技术,之前我已经写过一篇文章详细介绍了一下。不了解反射相关概念的同学可以阅读Java反射。

序列化(Serialization)与反序列化(Deserialization)是 Java 编程中非常重要的概念,尤其是在分布式系统、网络通信和持久化存储等场景下。它们用于将对象转换为一种格式,以便可以轻松地保存到文件或通过网络传输,并且可以在稍后的时间点恢复回原始对象。

实现

java 复制代码
public class Test31 {
    public static void main(String[] args) {
        Cat cat = new Cat(1, "bill");
        String s = SerializationUtils.toString(cat);
        System.out.println(s);
        Cat cat1 = (Cat) SerializationUtils.fromString(s);
        System.out.println(SerializationUtils.toString(cat1));
    }
}

class Cat{
    private int age;
    private String name;

    public Cat() {

    }

    public Cat(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

我们新建SerializationUtils类实现我们序列化与反序列化,SerializationUtils.toString()用来把一个对象序列化成一个字符串; SerializationUtils.fromString()用来把一个字符串反序列化成一个对象。

SerializationUtils.toString()序列化方法

java 复制代码
    public static String toString(Object obj) {
        try {
            Class<? > cls = obj.getClass();
            StringBuilder sb = new StringBuilder();
            sb.append(cls.getName() + "#");
            for(Field f : cls.getDeclaredFields()) {
                f.setAccessible(true);
                sb.append(f.getName() + "=" + f.get(obj).toString() + "#");
            }
            return sb.toString();
        } catch(IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

我们通过使用反射技术,把相关数据拼接成具有特定格式的字符串。

方法实现步骤:

  1. 获取对象的类,Class<?> cls = obj.getClass();
  2. 创建 StringBuilder 对象,追加类名
  3. 遍历字段
  4. 异常处理

SerializationUtils.fromString() 反序列化

java 复制代码
    public static Object fromString(String str) {
        try {
            String[] strs = str.split("#");
            if(strs.length < 1) {
                throw new Exception(str);
            }
            Class<? > cls = Class.forName(strs[0]);
            Object obj = cls.newInstance();
            if(strs.length > 1) {
                for(int i = 1; i < strs.length; i++) {
                    String[] fv = strs[i].split("=");
                    if(fv.length != 2) {
                        throw new IllegalArgumentException(strs[i]);
                    }
                    Field f = cls.getDeclaredField(fv[0]);
                    f.setAccessible(true);
                    setFieldValue(f, obj, fv[1]);
                }
            }
            return obj;
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
java 复制代码
private static void setFieldValue(Field field, Object obj, String value) throws IllegalAccessException {
    Class<?> fieldType = field.getType();
    if (fieldType == int.class || fieldType == Integer.class) {
        field.setInt(obj, Integer.parseInt(value));
    } else if (fieldType == double.class || fieldType == Double.class) {
        field.setDouble(obj, Double.parseDouble(value));
    } else if (fieldType == boolean.class || fieldType == Boolean.class) {
        field.setBoolean(obj, Boolean.parseBoolean(value));
    } else if (fieldType == String.class) {
        field.set(obj, value);
    } else {
        throw new IllegalArgumentException("Unsupported field type: " + fieldType);
    }
}

反序列化实际上就是,按照我们之前序列化定下的规则,反过来建立一个对象的过程。

方法实现步骤:

  1. 分割字符串,String\[\] strs = str.split("#");
  2. 检查类名是否存在,如果分割后的数组长度小于1,表示输入字符串不包含类名,抛出异常
  3. 加载类,Class<?> cls = Class.forName(strs0);
  4. 创建类的实例
  5. 处理字段值对
  6. 最后捕获异常,进行异常处理

总结

上面,我们写了一个简单的序列化与反序列化的案例,让我们体会到反射技术的强大。很明显,通过使用反射,我们的代码会具有更大的灵活性。但是需要注意的是,上面这个简答的序列化与反序列化只是一个让我们体会反射技术的案例,实际上要实现一个序列化与反序列化的通用方法要考虑很多安全性,性能与兼容性的处理。

相关推荐
懂点Tech3 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
云和数据.ChenGuang4 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠4 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
美狐美颜SDK开放平台5 小时前
视频美颜SDK试用DEMO阶段应该测试什么?直播APP接入实操指南
开发语言·人工智能·深度学习·音视频·美颜sdk·直播美颜sdk·第三方美颜sdk
dtq04245 小时前
C++小案例 - 日志实战
开发语言·c++
星夜离尘565 小时前
MATLAB ADC 码流触顶诊断:命中数、缺口分段与削顶不可辨识性
开发语言·matlab
码匠许师傅5 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
码匠许师傅6 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
silvamux_6 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
bkspiderx7 小时前
基于Socket的广播通信及C语言实现详解
c语言·开发语言·socket·广播·socket的广播通信