1. 程式人生 > >==和equals()的區別

==和equals()的區別

center 和equal 代碼 匹配 ole equal 其中 -- 可見

簡單的一句話說明就是:

== 比較Stack中的值(引用數據類型stack中存放的是對象的堆內存地址)

equals() 通常被覆寫為比較對象的值

那麽==和equals()之間到底有什麽具體的區別呢?

如果單從Object類或繼承於Object沒有做出任何覆寫操作的類來看,==和equals()之間沒有任何區別,equals方法由Object類提供,在Object中對equals的實現是這樣的:

public boolean equals(Object o){

return this == o;

}

但事實是API中的大部分類為我們重寫了equals方法,例如String中,equals

方法就被覆寫為了對值的比較,String中的equals是這樣操作的:

  1. 判斷傳入方法的字符串與當前字符串長度是否一致,如果不一致則沒有必要再進 行比較了,直接返回false
  2. 如果長度一致則把兩個支付串轉換成char數組,通過循環對兩個數組中的同位元素進行比較,其中有任意一對同位元素不一致則中斷循環,返回false
  3. 如果循環完成任然沒有跳出循環,則在循環自然中斷後返回true

由此可見,在String中的equals實際是在對字符串的每一個值進行比較

有時候==我們比較值的錯覺,如下列情況:

String a="Test";

String b="Test";

if(a= =b) ===> true

結果確實是我們想要得到的true,似乎比較成功了,但是!

這是因為當創建任何字符串文字時,JVM首先在字符串池中搜索該文字,並且如果找到匹配項,那麽同樣的引用將被賦予新的String。因此,我們得到了

a = = b===> true

簡而言之就是ab指向了相同的堆內存區

String Pool

b -----------------> "test" <-----------------a

但是,==在以下情況下失敗。

String a="test";

String b=new String("test");

if (a==b) ===> false

在這種情況下,new String("test")對於新的String將在堆內存區中創建新的引用賦予給b此時b所指向的內存地址與a指向不同
ifa == 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_1i_2的值進行一個修改看看

Integer i_1 = 128;

Integer i_2 = 128;

System.out.println(i_1 == i_2);

這個結果出人意料的返回了false,這是什麽原因?看看Integerequals方法實現過程

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的這種操作形式是調用IntegervalueOf方法,而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_1i_2直接賦值這個範圍時==返回為true,超出範圍自然返回為false

所以當你不知道到底應該使用哪個方法時,使用.equals()總是更好的。

文章原創。

若轉載,請註明出處:“來自蝸牛學院cto李懿老師”。

若沒有按照以上註明出處,一經發現必追究。

作者:蝸牛學院CTO李懿老師

==和equals()的區別