当前位置: 代码迷 >> JavaScript >> 比较 fastjson gson
  详细解决方案

比较 fastjson gson

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