1、Java當中的數據類型和「==」的含義java
一、基本數據類型:byte,short,char,int,long,float,double,boolean。他們之間的比較,應用雙等號==,比較的是他們的值。面試
二、引用數據類型:當他們用雙等號==比較的時候,比較的是它們在內存中的存放地址(確切的說,是堆內存地址)this
注:對於引用數據類型,除非是同一個new出來的對象,它們比較後的結果爲true,不然比較後結果爲false。由於每new一次,都會從新開闢堆內存空間。spa
2、equals()方法介紹:.net
Java當中全部的類都是繼承於object這個超類的,在object類中定義了一個equals方法,equals的源碼是這樣寫的:code
public boolean equals(Object obj) { //this - s1 //obj - s2 return (this == obj); }
能夠看到,這個方法的初始默認行爲是比較對象的內存地址值,通常來講,意義不大。因此,在一些類庫中這個方法被重寫了,如String、interger、date。在這些類當中equals有其自身的實現(通常都是用來比較對象的成員變量值是否相同),而不是比較類在堆內存中的存放地址了。因此說,對於符合數據類型之間進行equals比較,在沒有覆寫equals方法的狀況下,他們之間的比較仍是內存中的存放位置的地址值,跟雙等號==的結果相同;若是被重寫了,按照重寫的要求來。對象
咱們對上面的兩段內容作個總結:blog
==的做用:繼承
基本類型:比較的就是值是否相同內存
引用類型:比較的是地址值是否相同
equals的做用:
引用類型:默認狀況下比較的是地址值
注:不過,咱們能夠根據狀況本身重寫該方法,通常重寫都是自動生成,比較對象的成員變量值是否相同
3、string類的equals()方法
如今咱們拿String類來舉例:
咱們去\src\java\lang目錄中找到String類,發現equals方法被重寫以下:
public boolean equals(Obejct anObject){ if(this==anObject){ return true; } if(anObject instanceof String){ String anotherString = (String)anObject; int n = anotherString.value.lenght; 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()方法實際上是比較兩個字符串的內容。下面咱們經過實際代碼看看String類的比較。
一、舉例代碼以下:
public class StringDemo { public static void main(String[] args) { String s1 = "Hello"; String s2 = "Hello"; System.out.println(s1 == s2); // true } }
上方代碼中,用「==」比較s1和s2,返回的結果是true。
二、稍微改動一下程序,會有奇怪的發現:
public class StringDemo { public static void main(String args[]) { String str1 = "Hello"; String str2 = new String("Hello"); String str3 = str2; // 引用傳遞 System.out.println(str1 == str2); // false System.out.println(str1 == str3); // false System.out.println(str2 == str3); // true System.out.println(str1.equals(str2)); // true System.out.println(str1.equals(str3)); // true System.out.println(str2.equals(str3)); // true } }
上方第4行代碼中,咱們new了一個對象,用「==」比較s1和s2,返回的結果倒是false;而用用「equals」比較s1和s2,返回的結果是true。
爲了分析上面的代碼,咱們必須首先分析堆內存空間和棧內存空間,這一點很是重要:
看完上面的圖,再結合上面的代碼,就一目瞭然了。如今咱們能夠給本身出一道面試題:
面試題:請解釋字符串比較之中「==」和equals()的區別?
之後進行字符串相等判斷的時候都使用equals()。
三、再次更改程序:
public class ObjectDemo{ public static void main(String[] args) { String s1 = "Hello"; String s2 = new String("Hello"); s2 = s2.intern(); System.out.println(s1 == s2); // true System.out.println(s1.equals(s2)); // true } }
上述代碼中,Java.lanmg.String的intern()方法
「hello0」.intern()方法的返回值仍是字符串"hello",intern()方法檢查字符串池裏是否存在"hello",若是存在,就返回池裏的字符串;若是不存在,該方法會把"hello"添加到字符串池中,而後再返回它的引用。