一个简单的 Model .
public class Model { public int i = 0; public double d = 0.1; public String s = "s"; }
fastjson
如果要 json 化的对象是一个自定义类型的对象.
利用 com.alibaba.dubbo.common.bytecode 里面的工具类,
引用
Wrapper com.alibaba.dubbo.common.bytecode.Wrapper.makeWrapper(Class<?> c)
生成 Model 类的一个 Wrapper 类, Wrapper 类是一个利用 javassist 动态生产的一个包装工具类.比如 Model 类的 Wrapper 类里的方法有:
public Object getPropertyValue(Object o, String n) { org.alex.cases.json.compare.Model w; try { w = ((org.alex.cases.json.compare.Model) $1); } catch (Throwable e) { throw new IllegalArgumentException(e); } if ($2.equals("i")) { return ($w) w.i; } if ($2.equals("d")) { return ($w) w.d; } if ($2.equals("s")) { return ($w) w.s; } throw new com.alibaba.dubbo.common.bytecode.NoSuchPropertyException("Not found property \"" + $2 + "\" filed or setter method in class org.alex.cases.json.compare.Model."); } public void setPropertyValue(Object o, String n, Object v) { org.alex.cases.json.compare.Model w; try { w = ((org.alex.cases.json.compare.Model) $1); } catch (Throwable e) { throw new IllegalArgumentException(e); } if ($2.equals("i")) { w.i = ((Number) $3).intValue(); return; } if ($2.equals("d")) { w.d = ((Number) $3).doubleValue(); return; } if ($2.equals("s")) { w.s = (java.lang.String) $3; return; } throw new com.alibaba.dubbo.common.bytecode.NoSuchPropertyException("Not found property \"" + $2 + "\" filed or setter method in class org.alex.cases.json.compare.Model."); } public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws java.lang.reflect.InvocationTargetException { org.alex.cases.json.compare.Model w; try { w = ((org.alex.cases.json.compare.Model) $1); } catch (Throwable e) { throw new IllegalArgumentException(e); } throw new com.alibaba.dubbo.common.bytecode.NoSuchMethodException("Not found method \"" + $2 + "\" in class org.alex.cases.json.compare.Model."); }
里面的方法是遍历 Model 类的属性, 字符串拼接出来的.
然后利用一个 ConcurrentHashMap<Class<?>, Wrapper> 关联存储 Model.class() 和这个 Wrapper对象.
然后遍历 Model 各个属性,碰到基本类型或String就按照对应的格式输出, 碰到非基本类型,非 Map 非 Collection 非 Array ,那么再递归进去,再生成一个对应那个属性类型的 Wrapper,直到所有属性都为基本类型为止.
这样就生成了最后的 JSON.
gson
gson 里面有 TypeAdapterFactory 和 TypeAdapter 的概念
TypeAdapterFactory 是N个(大约30多种)类型(TypeAdapter) 的单例Factory,
比如有: 基本类型, Collection, Map, 自定义类(ReflectiveTypeAdapterFactory),URL , ENUM, Calendar 等.
还是以上面的 Model 类为例, Model 类就属于自定义类.
同样利用 TypeAdapterFactory 获取对应的 Model 的 TypeAdapter.
同样,在利用并发的 Map 关联 Map.class 和 对应的 TypeAdapter ,但 gson 的 Map 是用 Collections.synchronizedMap 实现同步的.
TypeAdapter 里面有一个
write(JsonWriter out, T value)
value 参数就是 Model 类的实际对象. 然后遍历属性写到 Writer out 流中,实际上JsonWriter 就是一个 StringWriter.
然后... StringWriter.toString , json 就出来了.
----------------------------------------------
- 比较来说, Gson 比 fastjson 考虑更全面, 对用 URL , UUID, BIT_SET, CALENDAR 等等,都有特定的输出规则.
- 小数量的调用 Gson 比 fastjson 快一点. (几十毫秒,可以毫不在意.猜测是因为 javassist 生成新的 Wrapper 类导致,因为还要编译的.)
- 大数量的调用 fastjson 比 Gson 快. (千万级别的.还不太确定为什么会变快, 猜测是 gson 的反射调用,毕竟比不上 fastjson Wrapper 类的真实调用.)
- 代码可阅读性: fastjson 比 Gson 好很多很多. fastjson 在要序列化对象的类型的判断上,使用的是 if else ,
- 如果普通日常使用,推荐使用 fastjson,简单易懂,并且是国内程序员开发,有问题可以较容易的获得支持. Gson 有对各种类型的属性支持, 如果有特殊类型json化需求可以选择 gson ,并自定义扩充.
Gson 使用的是遍历 TypeAdapterFactory集合,在每个 TypeAdapterFactory 里面做判断.而且使用了 N 多的匿名内部类, 想要一眼看出有哪些 TypeAdapterFactory 的实现都很困难.