java equals()和 ‘==’,‘!=’的使用和易錯點
阿新 • • 發佈:2017-08-24
原碼 寫博客 ima ole 引用 .com integer 操作 ==
關系操作符==和!=使用於所有對象的比較,返回boolean值,這兩個操作符常常會使第一次接觸java的程序員感到迷惑。下面是一個例子
public class EqualsTest {
public static void main(String[] args) {
Integer in1 = new Integer(100);
Integer in2 = new Integer(100);
System.out.println(in1==in2);
System.out.println(in1!=in2);
}
}
語句System.out.println(n1==n2)將打印出括號內的比較式的布爾值結果。讀者可能認為輸出結果先是true,再是false,因為兩個Integer對象都是相同的。但是盡管對象的內容相同,然而對象的引用(每new一個對象就是一個引用)卻是不同的,而==和!=比較的就是對象的引用。所有輸出結果實際先是false,再是true。其實這裏主要是理解==這個操作關系符就夠了。
談到 == 關系操作符我們肯定會想到equals()方法,再看下下面的例子:
public class EqualsTest {
public static void main(String[] args) {
Integer in1 = new Integer(100);
Integer in2 = new Integer(100);
System.out.println(in1.equals(in2));
}
}
這裏輸出的結果是true。問題來了,到這裏我們是否能夠得到這樣的結論:
‘==’ 關系操作符比較的是對象的引用,而 equals() 比較的是對象的實際內容。
先別急著下結論,我們再看看下面的例子:public class EqualsTest {
public static void main(String[] args) {
Value v1 = new Value(100);
Value v2 = new Value(100);
System.out.println("v1.equals(v2)? "+v1.equals(v2));
}
}
class Value{
int i;
public Value(int i){
this.i = i;
}
}
出乎意料的這裏的輸出實際結果為false,這就讓人難以理解了啊!說明上面的結論不正確了啊,這樣的話這個equals()就有點坑爹了啊。為了搞清楚這個問題,下面我們來追蹤下equals()這個方法。
首先我們得先明白這個equals是哪來的,由上面的代碼我們可以看到Value這個對象壓根就沒有equals()方法,那麽equals從哪裏呢?
如果在創建類的時候沒有聲明要繼承的類,那麽java就默認把它繼承Object類。所以Object就是所有類的父類。
這樣我們就明白了equals()來自Value類的父類Object,下面我們來看下Object的equals()這個方法:
從上面的代碼可以看出Object的equals方法比較的是對象的引用而不是對象的實際內容,這時我們的一個疑問是:
為什麽Integer的equals()方法比較的是對象的實際內容?
為了解答這個問題,我們來看看Integer類的原碼:
通過上面四張截圖我們就知道了,Integer已經覆蓋了Object的equals()方法,使得Interger的equals()方法比較的是對象的實際內容值(int value)。
現在我把Value也重寫下equals()方法,代碼如下:public class EqualsTest {
public static void main(String[] args) {
Value v1 = new Value(100);
Value v2 = new Value(100);
System.out.println(v1.equals(v2));
}
}
class Value{
int i;
public int getValue(){
return i;
}
public Value(){
}
public Value(int i){
this.i = i;
}
public boolean equals(Object obj){
if(obj instanceof Value){
return i ==((Value) obj).getValue();
}
return false;
}
}
這時輸出的結果就是我們想要的結果:true。
這時我們就可以得出結論:
‘==’ 關系操作符比較的是對象的引用,而Object類的equals()比較的也是對象的引用,如果想要比較對象的實際內容可以覆蓋父類
(Object)的equals()方法,eg:java JDK 自帶的類:Integer,String等。
註:
當Integer i的值在 [-128,128) 的範圍內是,java就會把變量i當做一個變量,放到內存中;但如果不在這個範圍內,就會去new一個Integer對象,
所以當Ingeter值在 [-128,128)的範圍內時,‘==’比較的是對象的實際內容值,既變量的值而不是比較引用。
這是本人的第一篇博客,寫的不好,也可能有寫得不對的地方,請各位讀者能給出寶貴的意見,本人寫博客是為了加深對一些東西印象和理解。
2017/8/23
java equals()和 ‘==’,‘!=’的使用和易錯點