一个简单的 Model .
class="java">
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 ,
Gson 使用的是遍历 TypeAdapterFactory集合,在每个 TypeAdapterFactory 里面做判断.而且使用了 N 多的匿名内部类, 想要一眼看出有哪些 TypeAdapterFactory 的实现都很困难.
- 如果普通日常使用,推荐使用 fastjson,简单易懂,并且是国内程序员开发,有问题可以较容易的获得支持.
Gson 有对各种类型的属性支持, 如果有特殊类型json化需求可以选择 gson ,并自定义扩充.