==和equals()的區別
簡單的一句話說明就是:
== 比較Stack中的值(引用數據類型stack中存放的是對象的堆內存地址)。
equals() 通常被覆寫為比較對象的值
那麽==和equals()之間到底有什麽具體的區別呢?
如果單從Object類或繼承於Object沒有做出任何覆寫操作的類來看,==和equals()之間沒有任何區別,equals方法由Object類提供,在Object中對equals的實現是這樣的:
public boolean equals(Object o){
return this == o;
}
但事實是API中的大部分類為我們重寫了equals方法,例如String中,equals
- 判斷傳入方法的字符串與當前字符串長度是否一致,如果不一致則沒有必要再進 行比較了,直接返回false
- 如果長度一致則把兩個支付串轉換成char數組,通過循環對兩個數組中的同位元素進行比較,其中有任意一對同位元素不一致則中斷循環,返回false
- 如果循環完成任然沒有跳出循環,則在循環自然中斷後返回true
由此可見,在String中的equals實際是在對字符串的每一個值進行比較
但有時候==確讓我們在比較值的錯覺,如下列情況:
String a="Test";
String b="Test";
if(a= =b) ===> true
結果確實是我們想要得到的true,似乎比較成功了,但是!
這是因為當你創建任何字符串文字時,JVM首先在字符串池中搜索該文字,並且如果找到匹配項,那麽同樣的引用將被賦予新的String。因此,我們得到了
(a = = b)===> true
簡而言之就是a和b指向了相同的堆內存區
String Pool
b -----------------> "test" <-----------------a
但是,==在以下情況下失敗。
String a="test";
String b=new String("test");
if (a==b) ===> false
在這種情況下,new String("test")對於新的String將在堆內存區中創建新的引用賦予給b,此時b所指向的內存地址與a指向不同
if(a == b)===> false。
String Pool
"test" <-------------------- a
Heap
"test" <-------------------- b
那在Integer等包裝類型又會如何呢:
我們不妨來看看下面這個實驗
Integer i_1 = 1;
Integer i_2 = 1;
Integer i_3 = new Integer(1);
System.out.println(i_1.equals(i_2)); //true
System.out.println(i_1.equals(i_3)); //true
System.out.println(i_1 == i_2); //true
System.out.println(i_1 == i_3); //false
好了,看上去一切真相大白,這個結果和我們期望的一模一樣,真是這樣嗎?我們把i_1和i_2的值進行一個修改看看
Integer i_1 = 128;
Integer i_2 = 128;
System.out.println(i_1 == i_2);
這個結果出人意料的返回了false,這是什麽原因?看看Integer的equals方法實現過程
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
這個方法告訴我們,Integer其實還是在用==做對象的比較,其中的value是一個int類型,在Integer中定義value是這樣的
private final int value;
這個方法毫無爭議,它和String中的equals有相同的思想。
我們在看看Integer i_1 = 1這段代碼,其實Integer i_1 = 1的這種操作形式是調用Integer的valueOf方法,而valueOf方法在Integer中的聲明如下:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high){
return IntegerCache.cache[i + (-IntegerCache.low)];
}
return new Integer(i);
}
不難發現,在某個範圍內Intger直接從IntegerCache中取值,超出了這個範圍則執行new Intger,而IntegerCache的範圍正好是-128~127,因此,當Integer i_1和i_2直接賦值這個範圍時==返回為true,超出範圍自然返回為false
所以當你不知道到底應該使用哪個方法時,使用.equals()總是更好的。
文章原創。
若轉載,請註明出處:“來自蝸牛學院cto李懿老師”。
若沒有按照以上註明出處,一經發現必追究。
作者:蝸牛學院CTO李懿老師
==和equals()的區別