List.contains()與自動拆箱


最近項目引入sonarQube這種代碼靜態檢查的東東,以前沒有人力和精力review,現在只要掃描一下項目,就發現很多有趣的地方.

有這么一段代碼:

List<Long> list = Lists.newArrayList();
Long a = 1L;
if(list.contains(a.longValue()){
 .....
}

這里用到了一個手動拆箱,當然以上的代碼只是個示例,但是總體的邏輯是不變的,那么這個手動拆箱,實際上是這段代碼的原作者害怕出現Long==Long這種不會觸發自動拆箱的問題.

這里簡單說一下:

Long a1 = 1l;
Long a2 = 1l
System.out.println(a1==a2); //雖然相等但是沒有觸發自動拆箱,實際上這里是由於Long的緩存機制,的確引用的是同一個對象
Long b1=new Long(1);
Long b2=new Long(1);
System.out.println(b1==b2); //沒有觸發拆箱,不是同一個對象,故不相等

所以為了確保觸發自動拆箱,故原作者自己手動拆箱達成Long==long這種滿足自動拆箱原則的條件.

但是呢,sonarQube提示這個其實沒必要,所以看一下List.contains()這個方法到底是如何實現的好了:

    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

發現其實調用的是equals方法,那么Long的equals方法實現:

    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }

可以看到其實已經拆箱比較了,故原作者其實是想多了,這里無需手動拆箱直接調用即可,即原例子中直接 list.contains(a)即可判斷.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM