原創文章,轉載時請註明做者:jmppok 及 出處 Java對象序列化小結 。
java
在Java中常常會用到對象序列化的地方,好比在持久化存儲對象時,傳輸對象時等。目前Java對象的序列化有不少種,可參見「Java序列化工具大全及性能比較」,但我的認爲大體可分爲4類:json
優勢是:能夠本身控制Serializable的實現,十分靈活,用戶能夠本身控制序列化的內容,順序等等,若是實現比較好的話,體積小,效率高。數據結構
缺點是:序列化對象必須事先實現Serializable接口,限制比較大。而且用戶需事先實現Serializable接口,工做量相對較大。工具
我的不太推薦。性能
優勢是:用戶經過中間語言定義數據結構,能夠生成大部分語言(C/C++/Java/C#/Python/Javascript等等)對應的代碼,使用起來十分方便,且序列化效率高,體積小。測試
缺點是:用戶需事先定義數據結構,由於限制了使用範圍。
this
通常推薦。spa
優勢是:可序列化任意的Java對象。.net
缺點是:效率相對較低,序列化後體積較大。在反序列化時,必需要指定須要反序列化的數據的Class,我的認這一點很是不爽。code
以下所示:
Persion類
public class Persion { public String name; public int age; public Persion(String name, int age) { this.name = name; this.age = age; } public Persion() { } }
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等序列化工具成爲你們的首選。
十分推薦。
費話很少說,直接上代碼:
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);