千里之行,始於足下。
在Java平常開發中,常常會碰見判斷兩個對象或者兩個值是否相等的狀況,而經常使用的判斷方法就是「==」和「equals」,今天就來講說這兩個的區別。緩存
主要用來判斷兩個對象的引用地址是否相同;
因此若是「==」兩邊的是兩個對象,那麼判斷的就是是否爲同一對象;
注1:若是對象的引用值是放在常量池中,例如字符串,相同字符串的引用地址相同,因此「abc"=="abc"的結果爲true。而經過new String()來聲明的,因爲引用地址不一樣,new String("abc") == new String("abc") 結果爲false。this
String A = "abc"; String B = "abc"; System.out.println(A == B); //true String a = new String("abc"); String b = new String("abc"); System.out.println(a == b); //false //ps:這裏String推薦使用equals來判斷是否相等,由於是舉例說明問題,因此強行用了==
注2:當判斷基本類型時,是直接比較引用指向堆裏面的具體值。code
equals是Object類中的一個方法,其默認是使用「==」來判斷兩個對象是否相等:對象
public boolean equals(Object obj) { return (this == obj); }
因此若是一個對象沒有重寫equals方法,那麼對比都是引用地址。開發
equals要求知足幾個特性:字符串
而在平常使用中已經重寫了equals的經常使用類,有String,Integer等。源碼
直接上源碼:hash
public boolean equals(Object anObject) { if (this == anObject) { //判斷引用地址是否相等 return true; } if (anObject instanceof String) { //傳入的參數是否爲String String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { //判斷兩個字符串長度是否相等 char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { //循環判斷兩個字符串的每一位字符 if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
能夠看到,當引用地址不相同時,String的equals時判斷兩個字符串的長度和每一位字符是否相等。循環
仍是直接上源碼:引用
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); //這裏的value是int類型的 } return false; }
Integer的equals是把兩個Integer對象轉化成基本類型int再經過==進行比較。
說到Integer,說一個遇到的坑:
Integer a = Integer.valueOf("127"); Integer b = Integer.valueOf("127"); Integer c = Integer.valueOf("128"); Integer d = Integer.valueOf("128"); System.out.println(a==b); //true System.out.println(c==d); //false
這裏是由於,對於Integer的valueOf存在一個-128~127緩存:
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) //low=-128,high=127 return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
因此當值在緩存裏的時候,valueOf並無new 對象,從而致使裏a==b爲true。因此對於Integer大小的判斷,推薦使用equals。
「==」和「equals」在沒有重寫Object裏equals方法的類裏,他們是同樣的。
而在平常的開發過程當中,類裏能夠重寫equals方法用來判斷兩個類是否相同。例如對於一個以手機號爲惟一標識的項目裏,能夠只判斷手機號就能確認兩個對象是否相等。
ps:再多說一句,通常重寫equals時也會重寫hashCode方法,至於爲何重寫hashCode方法,下次再說吧。