Java对象序列化小结

来源:互联网 发布:备案的域名 编辑:程序博客网 时间:2024/06/03 13:15

原创文章,转载时请注明作者: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 在CODE上查看代码片派生到我的代码片
  1. public class Persion {  
  2.     public String name;  
  3.     public int    age;  
  4.   
  5.     public Persion(String name, int age) {  
  6.         this.name = name;  
  7.         this.age = age;  
  8.     }  
  9.   
  10.     public Persion() {  
  11.   
  12.     }  
  13. }  

Gson序列化/反序列化测试
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class TestGson {  
  2.   
  3.     /** 
  4.      * @author ligh4 2015年3月19日下午5:32:34 
  5.      * @param args 
  6.      */  
  7.     public static void main(String[] args) throws Exception {  
  8.   
  9.         Map<Integer, Map<String, Persion>> classes = new Hashtable<Integer, Map<String, Persion>>();  
  10.   
  11.         Map<String, Persion> map = new HashMap<String, Persion>();  
  12.         map.put("ligh1"new Persion("ligh1"30));  
  13.         map.put("ligh2"new Persion("ligh2"30));  
  14.   
  15.         classes.put(1, map);  
  16.   
  17.         String json = new Gson().toJson(classes);  
  18.   
  19.         Map<Integer, Map<String, Persion>> cls = new Gson().fromJson(json,  
  20.                 new TypeToken<Map<Integer, Map<String, Persion>>>() {  
  21.                 }.getType());  
  22.   
  23.         System.out.println(cls.get(1).get("ligh2").name);  
  24.   
  25.     }  
  26. }  

看到Gson反序列化时了么?

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. Map<Integer, Map<String, Persion>> cls = new Gson().fromJson(json,  
  2.         new TypeToken<Map<Integer, Map<String, Persion>>>() {  
  3.         }.getType());  

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


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

十分推荐。


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

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

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public static void main (String[] args) throws Exception {  
  2.   
  3.   
  4.     Map<String, Persion> map = new HashMap<String, MapTest.Persion>();  
  5.     map.put("ligh1"new Persion("ligh1"30));  
  6.     map.put("ligh2"new Persion("ligh2"30));  
  7.   
  8.     Map<Integer, Map<String, Persion>> classes = new Hashtable<Integer, Map<String, Persion>>();  
  9.   
  10.     classes.put(1, map);  
  11.   
  12.   
  13.     Kryo kryo = new Kryo();  
  14.   
  15.     ByteArrayOutputStream buffer = new ByteArrayOutputStream();  
  16.     Output output = new Output(buffer);  
  17.     kryo.writeClassAndObject(output, classes);  
  18.     output.flush();  
  19.   
  20.     byte[] datas = buffer.toByteArray();  
  21.     System.out.println(datas.length);  
  22.   
  23.     Input input = new Input(datas);  
  24.   
  25.     Map<String, Persion> map2 = (Map)((Map)kryo.readClassAndObject(input)).get(1);  
  26.     Persion p1 = map2.get("ligh2");  
  27. }  

看到强大之处了吧?
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. kryo.writeClassAndObject(output, classes);  
  2. <pre name="code" class="java">kryo.readClassAndObject(input);  
使用十分方便。

不过什么Output,Input貌似也有点Out了,来一个简单的封装:

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class ObjectSerialization {  
  2.   
  3.     /** 
  4.      * @author ligh4 2015年3月23日下午1:32:04 
  5.      * @param obj 
  6.      * @return null if failed. 
  7.      * @throws Exception 
  8.      */  
  9.     public static synchronized String ToString(Object obj) {  
  10.         Kryo kryo = new Kryo();  
  11.   
  12.         ByteOutputStream stream = new ByteOutputStream();  
  13.         Output output = new Output(stream);  
  14.         kryo.writeClassAndObject(output, obj);  
  15.         output.flush();  
  16.   
  17.         String str = null;  
  18.         try {  
  19.             byte[] bytes = stream.getBytes();  
  20.             str = new String(bytes, "ISO8859-1");  
  21.         } catch (Exception e) {  
  22.             str = null;  
  23.         } finally {  
  24.             output.close();  
  25.             stream.close();  
  26.         }  
  27.   
  28.         return str;  
  29.     }  
  30.   
  31.     /** 
  32.      * @author ligh4 2015年3月23日下午1:32:19 
  33.      * @param str 
  34.      * @return null if failed. 
  35.      * @throws Exception 
  36.      */  
  37.     public static synchronized Object FromString(String str) {  
  38.   
  39.         Kryo kryo = new Kryo();  
  40.   
  41.         try {  
  42.             byte[] bytes = str.getBytes("ISO8859-1");  
  43.             Input input = new Input(bytes);  
  44.             Object obj = kryo.readClassAndObject(input);  
  45.             input.close();  
  46.             return obj;  
  47.         } catch (Exception e) {  
  48.             return null;  
  49.         }  
  50.   
  51.     }  
  52.   
  53.     static class Persion {  
  54.         public String name;  
  55.         public int    age;  
  56.   
  57.         public Persion(String name, int age) {  
  58.             this.name = name;  
  59.             this.age = age;  
  60.         }  
  61.   
  62.         public Persion() {  
  63.   
  64.         }  
  65.     }  
  66.   
  67.     /** 
  68.      * @author ligh4 2015年3月20日下午4:07:50 
  69.      * @param args 
  70.      */  
  71.     @SuppressWarnings({ "unchecked""rawtypes""unused" })  
  72.     public static void main(String[] args) throws Exception {  
  73.   
  74.         Map<String, Persion> map = new HashMap<String, Persion>();  
  75.         map.put("cn1"new Persion("中国1"30));  
  76.         map.put("cn2"new Persion("中国2"30));  
  77.   
  78.         Map<Integer, Map<String, Persion>> classes = new HashMap<Integer, Map<String, Persion>>();  
  79.   
  80.         classes.put(1, map);  
  81.   
  82.         String str = ObjectSerialization.ToString(classes);  
  83.   
  84.         System.out.println(str.length() + ":" + str);  
  85.   
  86.         Map<String, Persion> map2 = (Map) ((Map) ObjectSerialization.FromString(str)).get(1);  
  87.   
  88.         Persion p1 = map2.get("cn2");  
  89.     }  
  90. }  

使用更加方便了:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. String str = ObjectSerialization.ToString(classes);  
  2. ObjectSerialization.FromString(str)).get(1); 


来自:http://blog.csdn.net/jmppok/article/details/44563407

0 0
原创粉丝点击