【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(strs[0]);
  4. 创建类的实例
  5. 处理字段值对
  6. 最后捕获异常,进行异常处理

总结

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

相关推荐
探索java5 分钟前
Java 深入解析:JVM对象创建与内存机制全景图
java·jvm
zhangfeng11335 分钟前
python 数据分析 单细胞测序数据分析 相关的图表,常见于肿瘤免疫微环境、细胞亚群功能研究 ,各图表类型及逻辑关系如下
开发语言·python·数据分析·医学
Sylvia-girl12 分钟前
Java---IDEA
java·开发语言·intellij-idea
Z_W_H_18 分钟前
【Springboot】Bean解释
java·开发语言
Otaku love travel1 小时前
老系统改造增加初始化,自动化数据源配置(tomcat+jsp+springmvc)
java·tomcat·初始化·动态数据源
DKPT1 小时前
Java设计模式之行为型模式(责任链模式)介绍与说明
java·笔记·学习·观察者模式·设计模式
L_autinue_Star2 小时前
手写vector容器:C++模板实战指南(从0到1掌握泛型编程)
java·c语言·开发语言·c++·学习·stl
晨岳2 小时前
CentOS 安装 JDK+ NGINX+ Tomcat + Redis + MySQL搭建项目环境
java·redis·mysql·nginx·centos·tomcat
执笔诉情殇〆2 小时前
前后端分离(java) 和 Nginx在服务器上的完整部署方案(redis、minio)
java·服务器·redis·nginx·minio
元气小嘉2 小时前
前端技术小结
开发语言·前端·javascript·vue.js·人工智能