前幾天在項目上看到代碼2個Long型變量判斷是否相等用的是==,代碼在測試環境部署測試沒有問題,放到預發環境就有問題,于是就在main進行了如下測試
public class TestDemo {
public static void main(String args[]){
Long a=50L;
Long b=50L;
Long c=5000l;
Long d=5000l;
Long e=new Long(18);
Long f=new Long(18);
System.out.println(a==b);
System.out.println(c==d);
System.out.println(e==f);
System.out.println(e.equals(f));
}
}
true
false
false
true
Process finished with exit code 0
從代碼運作結果來看判斷Long型變量不能用==,隻能用equal,那麼就分析下原因:
1首先我們把一個long型數值賦予給了Long對象,這個過程其實就是基本類型到包裝類到封裝,Java上叫做裝箱,其實就是Long對象調用Long.valueOf(long) 的操作
2那麼點進去Long.valueOf(long)的源碼
/**
* Returns a {@code Long} instance representing the specified
* {@code long} value.
* If a new {@code Long} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Long(long)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* Note that unlike the {@linkplain Integer#valueOf(int)
* corresponding method} in the {@code Integer} class, this method
* is <em>not</em> required to cache values within a particular
* range.
*
* @param l a long value.
* @return a {@code Long} instance representing {@code l}.
* @since 1.5
*/
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
看源碼上有個判斷,當值大于-128并且小于127的時候從JVM緩存取出值,否則就new一個新對象,這就是我們用==判斷會出問題的原因
3我們用equal為啥可以,我們看看Long對象的equals方法
/**
* Compares this object to the specified object. The result is
* {@code true} if and only if the argument is not
* {@code null} and is a {@code Long} object that
* contains the same {@code long} value as this object.
*
* @param obj the object to compare with.
* @return {@code true} if the objects are the same;
* {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
由代碼可以看出,用equal判斷,Long會自動調用longValue()方法後再對比
可見還是要養成多看看源碼的好習慣!