前段时间掀起了风风火火的去fastjson, 其他Json序列化方法, 又"重见天日"; 本来推荐使用gson作为替代(某些场景下Jackson); 但这位同学使用的net.sf.json, 但缺乏认知, 未经测试就上线,导致了问题。
Case
当JSONArray.fromObject(null)时, 结果也为null吗?
JSONArray jsonArray;
try {
jsonArray = JSONArray.fromObject(value);
} catch (Exception e) {
jsonArray = null;
LOGGER.error("parse jsonArray error.", e);
}
// 当value为null时,作者意图是进入此分支
if(jsonArray == null) {
...
}
Detect
首先我们给出结论是:
JSONArray jsonArray = JSONArray.fromObject(null);
jsonArray结果是包含JSONNull的, 长度为1的JSONArray,
JSONNull也并不是一个null object
那么让我们看看JSONArray.fromObject发生了什么
在工程当前使用的版本中, 是这么实现的
public static JSONArray fromObject(Object object, JsonConfig jsonConfig) {
// 通过JsonConfig可以对某些属性进行过滤,以及选择JSONArray存储方式(默认是是ArrayList)等等
fromObject(object, new JsonConfig());
}
...
public static JSONArray fromObject(Object object, JsonConfig jsonConfig) {
...
jsonArray = (new JSONArray()).element(object, jsonConfig);
...
}
最终在 net.sf.json.AbstractJSON#_processValue, 返回了JSONNull对象
protected Object _processValue(Object value, JsonConfig jsonConfig) {
// 命中这步逻辑:
if (JSONNull.getInstance().equals(null)) {
return JSONNull.getInstance();
}
....
}
那么为什么JSONNull.getInstance().equals(null)
这完全取决于equals方法的实现
public final class JSONNull implements JSON {
private static JSONNull instance = new JSONNull();
public static JSONNull getInstance() {
return instance;
}
....
public boolean equals(Object object) {
return object == null
|| object == this
|| object == instance
|| object instanceof JSONObject && ((JSONObject)object).isNullObject()
|| "null".equals(object);
}
}