天天看點

fastJson解析空指針異常與防範VS從Map、JSONObject取不存在鍵值對時的異常情況

0x01 問題描述

正常情況下fastJson解析失敗會抛異常,但解析字元串資料為null、”“、“ ”這些情況下,fastJson傳回null對象而不會抛異常,這樣在調用對象時就導緻了空指針異常的問題。

0x02 解決方案

對此,不亦對其進行了一個簡單的封裝,在上述情況解析出null對象時直接抛異常。

0x03 代碼

import com.alibaba.fastjson.JSON;

public class JsonUtil{
    public static <T> T parseObject(String text, Class<T> clazz) throws Exception{
        try {
            T t= JSON.parseObject(text,clazz);
            if(null==t) {
                throw new Exception("parseObject NullPointerException");
            }else {
                return t;
            }
        } catch (Exception e) {
            throw e;
        }
    }
}
           

1.在Map中取不存在的鍵值對時不會報異常,隻會傳回null。

@Test
    public void testMap() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("d", 10);
        Object b = map.get("c");
        System.out.println(b);
    }
           

//列印結果是:null。

結論:從map中取出不存在的鍵值對時不會報異常,會傳回null。

2.在JSONObject中取不存在的鍵值對時分兩種情況:

利用jSONObject.get(Object key)方法及get(String key)取不存在的鍵值對時不會報異常,會傳回null;但是利用jSONObject.getxxx(String key)方法取時會報空指針異常:

@Test
    public void testJSONObject() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("d", 10);
        JSONObject jSONObject = JSONObject.fromObject(map);
        int xx = jSONObject.getInt("d");
        System.out.println(xx);
        // 從jSONObject中用get(Object key)方法取出不存在的鍵值對時不會報異常,會傳回null
        Object y = jSONObject.get("dd");
        System.out.println(y);
        // 從jSONObject中用getxxx(String key)方法取出不存在的鍵值對時報異常
        String y2 = jSONObject.getString("dd");
        System.out.println(y2);
    }
           

但是使用fastjson就不會出現這種錯誤,主要是還是兩者源碼方法的實作邏輯不同:

1.net.sf.json.JSONObject      
public String getString(String key) {
        this.verifyIsNull();
        Object o = this.get(key);
        if (o != null) {
            return o.toString();
        } else {
            throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] not found.");
        }
    }
           
2.com.alibaba.fastjson.JSONObject      
public String getString(String key) {
        Object value = this.get(key);
        return value == null ? null : value.toString();
    }
           

對null處理時會報空指針異常:

@Test
    public void testNull() {
        Object o = null;
        System.out.println(o);
        String s = (String) o;
        System.out.println(s);
        // System.out.println(s.getClass());
        User u = (User) o;
        System.out.println(u);
        // System.out.println(u.getClass());
    }
           

//列印結果:

//null

//null

//null

分析可知:不管null是何種類型,Object null或者String null或者其他類型的null,調用getClass()方法時都會報空指針異常。

如果是Object null,則可以轉為其他類型的null,因為其他類型都是Object的子類。但是其他類型的null不能随便轉類型,除非是有父子關系的類型。例如,如果String類型的想轉為User類型的,就會有編譯錯誤,說Cannot cast from String to User。