最近項目引入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)即可判斷.