我天!xx.equals(null) 是什么騷操作??
文末有驚喜
問題背景
我的天,最近做 Code Review 看到一個同事的騷操作,他寫了一個工具類,大概是這樣的:
public?static?boolean?isNull(Object?object){
????return?null?==?object?||?object.equals(null);
}
判斷空,一般不是?null == object?就夠了,object.equals(null)?是什么騷操作?
寫程序這么多年,第一次看這樣的寫法,當(dāng)時(shí)我就提出質(zhì)疑了,同事拍著胸脯和我說,有個銀行的請求參數(shù)必須得這么寫,不然就驗(yàn)證不了。
我當(dāng)時(shí)還在想,這是 JDK 出的什么新類型么,覺得還是不科學(xué),考慮去跟下同事寫的代碼,然后用他所說的情況我親自去驗(yàn)證一下。
看了下,這是個老業(yè)務(wù)系統(tǒng),同事用了?json-lib?這個包,歷史的江湖確實(shí)有這個包的存在,我之前也用過,不過后來這玩意就沒怎么用了,現(xiàn)在都是?Gson、Jackson?的天下了。
如下面?json-lib?例子所示:
public?static?void?main(String[]?args)?{
????String?jsonString?=?"{\"name\":?\"hi\",\"sex\":?\"boy\",?\"age\":?null}";
????JSONObject?jsonObject?=?net.sf.json.JSONObject.fromObject(jsonString);
????Object?age?=?jsonObject.get("age");
????//?輸出:null
????System.out.println("age:?"?+?age);
????//?輸出:false
????System.out.println("age?==?null:?"?+?(age?==?null));
????//?輸出:true
????System.out.println("age.equals(null):?"?+?(age.equals(null)));
}
我天!大家看到結(jié)果了吧,問題確實(shí)也如同事所說,一定要用?object.equals(null)?寫法才行,不相信結(jié)果的大家也可以親自驗(yàn)證一下。
納了悶了,這樣寫,我傳一個?null?值過去不是報(bào)空指針了么?這樣寫肯定有問題,繼續(xù)深挖!
問題分析
從?fromObject?方法加載 JSON 串開始源碼深入分析,找到了這個神奇解析?null?值的源碼:

原來,JSON 串中的?null?值被解析成了它內(nèi)部的?JSONNull?對象,然后再看下這個?JSONNull?的 equals 方法源碼:
public?boolean?equals(Object?object)?{
????return?object?==?null?||?
???????????object?==?this?||?
???????????object?==?instance?||?
???????????object?instanceof?JSONObject?&&
???????????((JSONObject)object).isNullObject()?||
???????????"null".equals(object);
}
問題就出在他所用的 JSON 工具類了!??!
equals 方法被重寫了……終于揭開了?object.equals(null)?的神秘面紗……
再來看下是否有新的更新包:

最新的版本停留在 2010 年 12 月,已經(jīng)是被淘汰的東西了。
另外,
json-lib?在 JDK 1.7+ 有性能影響。
解決方案
方法1:
換掉?object.equals(null),用?JSONNull?的實(shí)例去判斷:
public?static?boolean?isNull(Object?object){
????return?null?==?object?||?JSONNull.getInstance().equals(object);
}
方法2:
換掉?json-lib?庫,用主流的 ?Gson、Jackson,Json-lib 真不建議用了,另外?FastJson?也不建議用,漏洞比較多。
這個由于是老系統(tǒng),太多業(yè)務(wù)使用了這個庫,換掉的開發(fā)、測試成本和風(fēng)險(xiǎn)比較大,暫時(shí)考慮先用方案1先解決這個問題。
給大家推薦一本相當(dāng)不錯的書
書名:java并發(fā)編程指南
全書分為基礎(chǔ)、進(jìn)階、拓展和實(shí)戰(zhàn)四大篇,體系化講解Java高并發(fā)編程技術(shù)
深入:深度剖析Java并發(fā)包、Dubbo等框架源碼設(shè)計(jì),領(lǐng)略大咖的代碼設(shè)計(jì)藝術(shù)
實(shí)戰(zhàn):分布式系統(tǒng)設(shè)計(jì)理論與項(xiàng)目實(shí)戰(zhàn)相結(jié)合,懂理論,能落地,手把手教你吃透高并發(fā)項(xiàng)目核心技術(shù)
資源:附贈全書案例源代碼,知其然更知其所以然,快速上手不用愁
書籍內(nèi)容
《Java高并發(fā)編程指南》內(nèi)容由淺入深,采用理論與實(shí)踐相結(jié)合的方式講解Java高并發(fā)編程的相關(guān)知識。Java多線程基礎(chǔ)、Java并發(fā)包相關(guān)類的使用與設(shè)計(jì)原理,拓展講解分布式系統(tǒng)設(shè)計(jì)的相關(guān)原理、挑戰(zhàn)、涉及的相關(guān)框架、中間件等;對流行的Java開源框架的源碼設(shè)計(jì)進(jìn)行分析,結(jié)合實(shí)現(xiàn)一個簡易版的秒殺系統(tǒng)來介紹如何基于Java語言實(shí)現(xiàn)一個高并發(fā)系統(tǒng)。
推薦閱讀
