Java中equals和==的區別

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():比較的是兩個字符串的內容,屬於內容比較。

之後進行字符串相等判斷的時候都使用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"添加到字符串池中,而後再返回它的引用。

 

素小暖講Java@目錄

相關文章
相關標籤/搜索