资讯专栏INFORMATION COLUMN

java常用序列化与反序列化方法

zhkai / 2048人阅读

摘要:序列化工具类序列化工具的序列化与反序列化使用实现序列化和反序列化反序列化时,必须要有默认构造函数,否则报错使用序列化缓存此类分别包含序列化序列化序列化三种序列化方式。

序列化工具类

序列化即将对象序列化为字节数组,反序列化就是将字节数组恢复成对象。
主要的目的是方便传输和存储。

序列化工具类:

public class SerializeUtil {

    private static Map, Schema> cachedSchema = new ConcurrentHashMap<>();

    private static Objenesis objenesis = new ObjenesisStd(true);

    /**
     * jdk 序列化工具的序列化与反序列化
     *
     * @param object
     * @return
     * @throws IOException
     */
    public static byte[] JDKObjectToBytes(Object object) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutput objectOutput = new ObjectOutputStream(byteArrayOutputStream);
        objectOutput.writeObject(object);
        return byteArrayOutputStream.toByteArray();
    }

    public static  T JDKBytesToObject(byte[] bytes, Class clazz) throws Exception {
        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        Object object = objectInputStream.readObject();
        return (T) object;
    }

    /**
     * 使用fastjson实现序列化和反序列化
     *
     * @param object
     * @return
     */
    public static byte[] FastJsonObjectToBytes(Object object) {
        byte[] bytes = JSON.toJSONBytes(object);
        return bytes;
    }

    /**
     * fastjosn反序列化时,class必须要有默认构造函数,否则报错
     * @param bytes
     * @param clazz
     * @param 
     * @return
     */
    public static  T FastJsonBytesToObject(byte[] bytes, Class clazz) {
        return (T) JSON.parseObject(bytes, clazz);
    }

    /**
     * 使用protostuff序列化
     * @param obj
     * @param 
     * @return
     */
    public static  byte[] serialize(T obj) {
        Class cls = (Class) obj.getClass();
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            Schema schema = getSchema(cls);
            return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            buffer.clear();
        }
    }

    public static  T deserialize(byte[] data, Class cls) {
        try {
            T message = objenesis.newInstance(cls);
            Schema schema = getSchema(cls);
            ProtostuffIOUtil.mergeFrom(data, message, schema);
            return message;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * 缓存schema
     * @param cls
     * @param 
     * @return
     */
    private static  Schema getSchema(Class cls) {
        Schema schema = (Schema) cachedSchema.get(cls);
        if (schema == null) {
            schema = RuntimeSchema.createFrom(cls);
            if (schema != null) {
                cachedSchema.put(cls, schema);
            }
        }
        return schema;
    }
}

此类分别包含jdk序列化、fastjson序列化、protobuf序列化三种序列化方式。

注意prostuff需要包含maven依赖:

        
        
            org.objenesis
            objenesis
            2.6
        

        
            io.protostuff
            protostuff-core
            1.4.0
        

        
            io.protostuff
            protostuff-runtime
            1.4.0
        
        
        
        
            com.alibaba
            fastjson
            1.2.31
        
使用

首先定义一个类用于测试,注意此类没有默认构造函数。

public class Monster implements Serializable{
    Integer hp;
    Integer mp;
    String name;
    Integer level;

    public Monster(String name,Integer level){
        this.name=name;
        this.level=level;
    }
    
    //省略getter、setter、hashCode、equals...
}

测试类:

public class SerializeUtilTest {

    Monster monster = new Monster("boss", 100);
    Class clazz = Monster.class;

    @Test
    public void jdkSerializeTest() throws Exception {
        byte[] bytes = SerializeUtil.JDKObjectToBytes(monster);
        System.out.println(bytes.length);
        Monster object = SerializeUtil.JDKBytesToObject(bytes,clazz);
        Assert.assertEquals(object, monster);
    }

    @Test(expected = com.alibaba.fastjson.JSONException.class)
    public void fastJsonSerializeTest(){
        byte[] bytes = SerializeUtil.FastJsonObjectToBytes(monster);
        System.out.println(bytes.length);
        Monster object = SerializeUtil.FastJsonBytesToObject(bytes,clazz);
        Assert.assertEquals(object, monster);
    }

    @Test
    public void serialize(){
        byte[] serialize = SerializeUtil.serialize(monster);
        System.out.println(serialize.length);
        Object deserialize = SerializeUtil.deserialize(serialize, clazz);
        Assert.assertEquals(deserialize,monster);
    }
}

输出分别为199、27、8。
可以看出jdk默认序列化方式的效率极低,protobuf效率和字节都非常高效。

特别注意:fastjson反序列化的对象必须要有默认构造函数,否则会报错。protostuff使用objenesis不需要默认构函数创建对象。但是json格式可读性好,性能也还可以,推荐性能不高的场景优先json格式,对性能要求高的场景使用protostuff。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67490.html

相关文章

  • Java开发中对象的列化与反列化

    摘要:在中,对象的序列化与反序列化被广泛应用到远程方法调用及网络传输中。相关接口及类为了方便开发人员将对象进行序列化及反序列化提供了一套方便的来支持。未实现此接口的类将无法使其任何状态序列化或反序列化。 序列化与反序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等。在网络传输过程中,可以...

    fox_soyoung 评论0 收藏0
  • Javag工程师成神之路(2019正式版)

    摘要:结构型模式适配器模式桥接模式装饰模式组合模式外观模式享元模式代理模式。行为型模式模版方法模式命令模式迭代器模式观察者模式中介者模式备忘录模式解释器模式模式状态模式策略模式职责链模式责任链模式访问者模式。 主要版本 更新时间 备注 v1.0 2015-08-01 首次发布 v1.1 2018-03-12 增加新技术知识、完善知识体系 v2.0 2019-02-19 结构...

    Olivia 评论0 收藏0
  • 你和阿里资深架构师之间,差的不仅仅是年龄(进阶必看)

    摘要:导读阅读本文需要有足够的时间,笔者会由浅到深带你一步一步了解一个资深架构师所要掌握的各类知识点,你也可以按照文章中所列的知识体系对比自身,对自己进行查漏补缺,觉得本文对你有帮助的话,可以点赞关注一下。目录一基础篇二进阶篇三高级篇四架构篇五扩 导读:阅读本文需要有足够的时间,笔者会由浅到深带你一步一步了解一个资深架构师所要掌握的各类知识点,你也可以按照文章中所列的知识体系对比自身,对自己...

    huaixiaoz 评论0 收藏0
  • JAVA运行时的泛型擦除与反列化的应用

    摘要:回到的第二方法的用法,通过上面的分析,我们可以知道,方法其实也是用来获取泛型的实际类型的,这样就可以将响应反序列化为带泛型的类型了。在很多反序列化的开源组件中,都用了这个原理例如的方法,所以我们会经常见到实例化的时候会多个花括号。 前段日子在使用google-http-client.jar 这个组件做http请求时,发现一件有趣的事情,具体代码如下: try { ...

    weizx 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<