您的位置:首页 > 编程语言 > Java开发

Java对象序列化小结

2016-11-15 16:44 344 查看
原创文章,转载时请注明作者:jmppok 及 出处
Java对象序列化小结。

在Java中经常会用到对象序列化的地方,比如在持久化存储对象时,传输对象时等。目前Java对象的序列化有很多种,可参见“Java序列化工具大全及性能比较”,但个人认为大致可分为4类:

1)序列化对象需要事先实现Serializable接口的,如Java原生的序列化,Hessian, FST-serialization等等。

优点是:可以自己控制Serializable的实现,十分灵活,用户可以自己控制序列化的内容,顺序等等,如果实现比较好的话,体积小,效率高。

缺点是:序列化对象必须事先实现Serializable接口,限制比较大。并且用户需事先实现Serializable接口,工作量相对较大。

个人不太推荐。

2)使用某种中间语言,事先定义对象的Schema,然后生成相应的Java/C++/Python代码, 如goole的protobuffer,flatbuffer,thrift,ice等等。

优点是:用户通过中间语言定义数据结构,可以生成大部分语言(C/C++/Java/C#/Python/JavaScript等等)对应的代码,使用起来十分方便,且序列化效率高,体积小。

缺点是:用户需事先定义数据结构,因为限制了使用范围。

一般推荐。

3)  通过开源工具,将对象直接序列化为XML,JSON等,如gson,fastjson等。

优点是:可序列化任意的Java对象。

缺点是:效率相对较低,序列化后体积较大。在反序列化时,必须要指定需要反序列化的数据的Class,个人认这一点非常不爽。

如下所示:

Persion类

[java]
view plain
copy





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

Gson序列化/反序列化测试

[java]
view plain
copy





public class TestGson {  
  
    /** 
     * @author ligh4 2015年3月19日下午5:32:34 
     * @param args 
     */  
    public static void main(String[] args) throws Exception {  
  
        Map<Integer, Map<String, Persion>> classes = new Hashtable<Integer, Map<String, Persion>>();  
  
        Map<String, Persion> map = new HashMap<String, Persion>();  
        map.put("ligh1", new Persion("ligh1", 30));  
        map.put("ligh2", new Persion("ligh2", 30));  
  
        classes.put(1, map);  
  
        String json = new Gson().toJson(classes);  
  
        Map<Integer, Map<String, Persion>> cls = new Gson().fromJson(json,  
                new TypeToken<Map<Integer, Map<String, Persion>>>() {  
                }.getType());  
  
        System.out.println(cls.get(1).get("ligh2").name);  
  
    }  
}  

看到Gson反序列化时了么?

[java]
view plain
copy





Map<Integer, Map<String, Persion>> cls = new Gson().fromJson(json,  
        new TypeToken<Map<Integer, Map<String, Persion>>>() {  
        }.getType());  

好像很不爽阿?不过相比需要事先实现Serializable接口和实现定义Schema生成代码,忍了。

实际上,在计算机硬件性能和带宽高速发展的今天,对序列化的效率和数据大小的追求逐渐下降。大部分公司追求的是项目的短,平,快,因此gson等序列化工具成为大家的首选。

十分推荐。

4)个人认为的终极序列化工具, 序列化任意对象。且在序列化反序列化时不需要人为指定类的信息,如Kryo。

费话不多说,直接上代码:

[java]
view plain
copy





public static void main (String[] args) throws Exception {  
  
  
    Map<String, Persion> map = new HashMap<String, MapTest.Persion>();  
    map.put("ligh1", new Persion("ligh1", 30));  
    map.put("ligh2", new Persion("ligh2", 30));  
  
    Map<Integer, Map<String, Persion>> classes = new Hashtable<Integer, Map<String, Persion>>();  
  
    classes.put(1, map);  
  
  
    Kryo kryo = new Kryo();  
  
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();  
    Output output = new Output(buffer);  
    kryo.writeClassAndObject(output, classes);  
    output.flush();  
  
    byte[] datas = buffer.toByteArray();  
    System.out.println(datas.length);  
  
    Input input = new Input(datas);  
  
    Map<String, Persion> map2 = (Map)((Map)kryo.readClassAndObject(input)).get(1);  
    Persion p1 = map2.get("ligh2");  
}  

看到强大之处了吧?

[java]
view plain
copy





kryo.writeClassAndObject(output, classes);  
<pre name="code" class="java">kryo.readClassAndObject(input);  

使用十分方便。
不过什么Output,Input貌似也有点Out了,来一个简单的封装:

[java]
view plain
copy





public class ObjectSerialization {  
  
    /** 
     * @author ligh4 2015年3月23日下午1:32:04 
     * @param obj 
     * @return null if failed. 
     * @throws Exception 
     */  
    public static synchronized String ToString(Object obj) {  
        Kryo kryo = new Kryo();  
  
        ByteOutputStream stream = new ByteOutputStream();  
        Output output = new Output(stream);  
        kryo.writeClassAndObject(output, obj);  
        output.flush();  
  
        String str = null;  
        try {  
            byte[] bytes = stream.getBytes();  
            str = new String(bytes, "ISO8859-1");  
        } catch (Exception e) {  
            str = null;  
        } finally {  
            output.close();  
            stream.close();  
        }  
  
        return str;  
    }  
  
    /** 
     * @author ligh4 2015年3月23日下午1:32:19 
     * @param str 
     * @return null if failed. 
     * @throws Exception 
     */  
    public static synchronized Object FromString(String str) {  
  
        Kryo kryo = new Kryo();  
  
        try {  
            byte[] bytes = str.getBytes("ISO8859-1");  
            Input input = new Input(bytes);  
            Object obj = kryo.readClassAndObject(input);  
            input.close();  
            return obj;  
        } catch (Exception e) {  
            return null;  
        }  
  
    }  
  
    static class Persion {  
        public String name;  
        public int    age;  
  
        public Persion(String name, int age) {  
            this.name = name;  
            this.age = age;  
        }  
  
        public Persion() {  
  
        }  
    }  
  
    /** 
     * @author ligh4 2015年3月20日下午4:07:50 
     * @param args 
     */  
    @SuppressWarnings({ "unchecked", "rawtypes", "unused" })  
    public static void main(String[] args) throws Exception {  
  
        Map<String, Persion> map = new HashMap<String, Persion>();  
        map.put("cn1", new Persion("中国1", 30));  
        map.put("cn2", new Persion("中国2", 30));  
  
        Map<Integer, Map<String, Persion>> classes = new HashMap<Integer, Map<String, Persion>>();  
  
        classes.put(1, map);  
  
        String str = ObjectSerialization.ToString(classes);  
  
        System.out.println(str.length() + ":" + str);  
  
        Map<String, Persion> map2 = (Map) ((Map) ObjectSerialization.FromString(str)).get(1);  
  
        Persion p1 = map2.get("cn2");  
    }  
}  

使用更加方便了:

[java]
view plain
copy





String str = ObjectSerialization.ToString(classes);  
ObjectSerialization.FromString(str)).get(1); 

来自:http://blog.csdn.net/jmppok/article/details/44563407
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: