Java面試題 equals()與"=="的區別?

面試官:請問 equals() 和 "==" 有什麼區別?java

應聘者:面試

  • equals()方法用來比較的是兩個對象的內容是否相等,因爲全部的類都是繼承自java.lang.Object類的,因此適用於全部對象,若是沒有對該方法進行覆蓋的話,調用的仍然是Object類中的方法,而Object中的equals方法返回的倒是==的判斷;ide

  • "==" 比較的是變量(棧)內存中存放的對象的(堆)內存地址,用來判斷兩個對象的地址是否相同,便是否是指相同一個對象。函數

 

equals()做用this

equals() 的做用是用來判斷兩個對象是否相等。 spa

equals() 定義在JDK的Object.java中。經過判斷兩個對象的地址是否相等(即,是不是同一個對象)來區分它們是否相等。源碼以下:對象

public boolean equals(Object obj) {
    return (this == obj);
}

既然Object.java中定義了equals()方法,這就意味着全部的Java類都實現了equals()方法,全部的類均可以經過equals()去比較兩個對象是否相等。可是,咱們已經說過,使用默認的「equals()」方法,等價於「==」方法。所以,咱們一般會重寫equals()方法:若兩個對象的內容相等,則equals()方法返回true;不然,返回fasle。blog

下面根據"類是否覆蓋equals()方法",將它分爲2類。繼承

  • 若某個類沒有覆蓋equals()方法,當它的經過equals()比較兩個對象時,其實是比較兩個對象是否是同一個對象。這時,等價於經過「==」去比較這兩個對象。內存

  • 咱們能夠覆蓋類的equals()方法,來讓equals()經過其它方式比較兩個對象是否相等。一般的作法是:若兩個對象的內容相等,則equals()方法返回true;不然,返回fasle。

下面,舉例對上面的2種狀況進行說明:

 

沒有覆蓋equals()方法的狀況

public class EqualsTest {
    public static void main(String[] args) {
        // 新建2個相同內容的Person對象,
        // 再用equals比較它們是否相等
        User user1 = new User("James", 100);
        User user2 = new User("James", 100);
        System.out.printf("比較結果:" + user1.equals(user2));
    }

    /**
     * @desc User類。
     */
    static class User {
        int age;
        String name;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String toString() {
            return name + " - " + age;
        }
    }
}

運行結果:

比較結果:false

結果分析:咱們經過 user1.equals(user2) 來「比較user1和user2是否相等時」。實際上,調用的Object.java的equals()方法,即調用的 (user1==user2) 。它是比較「p1和p2是不是同一個對象」。而由 user1 和 user2 的定義可知,它們雖然內容相同;但它們是兩個不一樣的對象,所以,返回結果是false。

 

覆蓋equals()方法的狀況

修改上面的EqualsTest,覆蓋equals()方法:

public class EqualsTest {
    public static void main(String[] args) {
        // 新建2個相同內容的Person對象,
        // 再用equals比較它們是否相等
        User user1 = new User("James", 100);
        User user2 = new User("James", 100);
        System.out.printf("比較結果:" + user1.equals(user2));
    }

    /**
     * @desc User類。
     */
    static class User {
        int age;
        String name;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String toString() {
            return name + " - " + age;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            User other = (User) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
    }
}

運行結果:

比較結果:true

結果分析:咱們在EqualsTest.java 中重寫了User的equals()函數:當兩個User對象的 name 和 age 都相等,則返回true。所以,運行結果返回true。

 

== 的做用

「==」:它的做用是判斷兩個對象的地址是否是相等。即判斷引用對象是否是指向的堆中的同一個對象,咱們知道,凡是new出來的對象都在堆中。而對象的引用都存放在棧中,具體來說就是放在棧幀中,咱們來看下面一段代碼:

public static void main(String[] args) {
        User user1 = new User("James", 100);
        User user2 = new User("James", 100);
        System.out.println("user1.equals(user2):" + user1.equals(user2));
        System.out.println("user1==user2:" + (user1==user2));
}

輸出結果:

user1.equals(user2):true
user1==user2:false

用內存圖表示以下:

指向的是堆中兩塊不一樣的區域,因此用 "==" 比較時返回的是false。

相關文章
相關標籤/搜索