Java对象序列化小结
2015-03-23 14:35
369 查看
原创文章,转载时请注明作者:jmppok 及 出处 Java对象序列化小结
。
在Java中经常会用到对象序列化的地方,比如在持久化存储对象时,传输对象时等。目前Java对象的序列化有很多种,可参见“Java序列化工具大全及性能比较”,但个人认为大致可分为4类:
缺点是:序列化对象必须事先实现Serializable接口,限制比较大。并且用户需事先实现Serializable接口,工作量相对较大。
个人不太推荐。
缺点是:用户需事先定义数据结构,因为限制了使用范围。
一般推荐。
缺点是:效率相对较低,序列化后体积较大。在反序列化时,必须要指定需要反序列化的数据的Class,个人认这一点非常不爽。
如下所示:
Persion类
Gson序列化/反序列化测试
看到Gson反序列化时了么?
好像很不爽阿?不过相比需要事先实现Serializable接口和实现定义Schema生成代码,忍了。
实际上,在计算机硬件性能和带宽高速发展的今天,对序列化的效率和数据大小的追求逐渐下降。大部分公司追求的是项目的短,平,快,因此gson等序列化工具成为大家的首选。
十分推荐。
看到强大之处了吧?
使用十分方便。
不过什么Output,Input貌似也有点Out了,来一个简单的封装:
使用更加方便了:
。
在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类
public class Persion { public String name; public int age; public Persion(String name, int age) { this.name = name; this.age = age; } public Persion() { } }
Gson序列化/反序列化测试
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反序列化时了么?
Map<Integer, Map<String, Persion>> cls = new Gson().fromJson(json, new TypeToken<Map<Integer, Map<String, Persion>>>() { }.getType());
好像很不爽阿?不过相比需要事先实现Serializable接口和实现定义Schema生成代码,忍了。
实际上,在计算机硬件性能和带宽高速发展的今天,对序列化的效率和数据大小的追求逐渐下降。大部分公司追求的是项目的短,平,快,因此gson等序列化工具成为大家的首选。
十分推荐。
4)个人认为的终极序列化工具, 序列化任意对象。且在序列化反序列化时不需要人为指定类的信息,如Kryo。
费话不多说,直接上代码: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"); }
看到强大之处了吧?
kryo.writeClassAndObject(output, classes); <pre name="code" class="java">kryo.readClassAndObject(input);
使用十分方便。
不过什么Output,Input貌似也有点Out了,来一个简单的封装:
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"); } }
使用更加方便了:
String str = ObjectSerialization.ToString(classes); ObjectSerialization.FromString(str)).get(1);
相关文章推荐
- Java对象序列化小结
- Java对象序列化小结
- Java对象序列化知识小结
- Java IO操作——对象序列化(Serializable接口、ObjectOutputStream、以及与Externalizable接口的用法和区别)
- Java对象序列化
- java对象序列化示例
- java 面向对象小结
- java对象序列化与反序列化
- Java对象的序列化和反序列化
- 理解Java对象序列化——Serializable接口
- 【java】理解Java对象序列化
- java提高篇(六)-----使用序列化实现对象的拷贝
- java语言编程IO流之对象序列化和ObjectInputStream与ObjectOutputStream
- Java对象序列化
- Java对象的序列化和反序列化
- Java对象序列化与反序列化一 JSON
- 关于Java对象序列化您不知道的5件事
- 深入理解java对象的序列化
- Java对象序列化ObjectOutputStream和ObjectInputStream示例
- 关于 Java 对象序列化您不知道的 5 件事