1. 程式人生 > 其它 >IDEA編譯器中equals方法原始碼解析

IDEA編譯器中equals方法原始碼解析

技術標籤:javaobject程式語言

由於Object類的equals方法通常不能讓人滿意,所以大家一般會對Object類中的equals方法進行重寫,達到比較滿意的效果,而IDEA編譯器中為我們提供了自動重寫equals方法的功能。下面就讓我們一起看看。
那麼在看equals自動重寫原始碼之前先來看看一段簡單的示範程式碼:

`import java.util.Objects;


public class Phone{
    private String brand;
    private double price;
    private int year;
    //方法
    public
Phone(){} public Phone(String brand,double price,int year){ this.brand=brand; this.price=price; this.year=year; } public String getBrand(){ return brand; } public double getPrice() { return price; } public void setPrice(double price)
{ this.price = price; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public void setBrand(String brand){ this.brand=brand; } @Override public boolean equals(Object o) { if
(this == o) return true; if (o == null || getClass() != o.getClass()) return false; Phone phone = (Phone) o; return Double.compare(phone.price, price) == 0 && year == phone.year && Objects.equals(brand, phone.brand); } @Override public int hashCode() { return Objects.hash(brand, price, year); } }
public class Test{
    public static void main(String[] args) {
        Phone p1=new Phone("huawei",3457,2021);
        Phone p2=new Phone("huawei",3457,2021);
        System.out.println(p1.equals(p2));
    }
}

其中今天重點分析的是equals方法,即:

 @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Phone phone = (Phone) o;
        return Double.compare(phone.price, price) == 0 &&
                year == phone.year &&
                Objects.equals(brand, phone.brand);
    }

首先大家看到這個方法應該是比較蒙的,那麼來看看IDEA到底使用了什麼邏輯實現了重寫equals方法。

首先說一說”==“和equals到底有何區別?

==

Java語言採用的是值傳遞,所以==比較的是值傳遞的值是否相等,那麼可能會有小夥伴問了,小銘,什麼是值傳遞?
簡單來說值傳遞傳遞的就是實際的值。
1.對於基本資料型別而言,值傳遞傳遞的是真實的值,比如說:

int a=10;
itn b=10;

那麼對於==而言,int整型的變數a,b,進行比較運算子 ==得到的結果是true,因為 ==比較的是實際的值,a=10,b=10,實際的值都是10,所以a,b相等。
2.對於引用資料型別而言,值傳遞傳遞的是地址的值。

equals:

那麼讓我們來看看equals在Object類中的原始碼:

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

實際上在Object類中,equals方法等同於==比較運算子,如果建立了一個引用資料型別的物件,那麼equals方法的功能也是同 ==相同,比較的是地址的值。那麼如何用equals方法在引用資料型別物件的比較中比較的是物件中屬性實際的值是否相同呢?
所以我們就引出了equals方法重寫:

 @Override
    public boolean equals(Object o) {
    

if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Phone phone = (Phone) o;
        return Double.compare(phone.price, price) == 0 &&
                year == phone.year &&
                Objects.equals(brand, phone.brand);
    }
if (this == o) return true;

在原始碼中,this指的是第一個物件,而o表示的是第二個物件。這句話的意思就是如果第一個物件(this)與第二個物件(o)地址的值相同,那麼就可以判定第一個物件(this)和第二個物件(o)是同一個物件,所以直接返回true,即:相同。

 if (o == null || getClass() != o.getClass()) return false;

第二句,如果第二個物件(o)是空,null值,那麼一定是不同,那麼返回的就是false,即第一個物件和第二個物件不同。
||是或者的意思,||後面連線的就是:
如果第一個物件(this,原始碼中的this被省略了,其實是this.getClass())和第二個物件(o)不是同一個類,那麼返回值就為false,即:第一個物件和第二個物件不同。

那麼,第二句連起來就是:

如果第二個物件(o)是空,null值,或者第一個物件(this,原始碼中的this被省略了,其實是this.getClass())和第二個物件(o)不是同一個類,那麼返回值為false,即:第一個物件和第二個物件不同。

 Phone phone = (Phone) o;

第三句,在第二句已經判斷完了,可以確定第一個物件(this)與第二個物件(o)的類是相同的,那麼由於第二個物件賦給了o,o是Object型別,如果第二個物件p2依然是Object型別那麼很顯然程式碼會報錯,只有第一個物件(this)與第二個物件(o)的類是相同的才可以互相equals比較,於是,這一句的核心就是將Object型別的物件p2強轉成Phone型別。

 return Double.compare(phone.price, price) == 0 &&
                year == phone.year &&
                Objects.equals(brand, phone.brand);

最後一句就非常簡單了,先來看看Double類下的API:
Double.compare
compare就是比較兩個double型別的值是否相等,在咱們的示範程式碼中,price變數是double基本資料型別,所以使用compare方法來比較兩個物件price的值是否相同。

第二句int基本資料型別就沒什麼好說的了,剛才也說了值傳遞,int基本資料型別直接把兩個物件int實際的值進行了比較。

那麼看第三句String型別的變數之前,咱們先了解一下Objects類的API:
在這裡插入圖片描述
在API中可以看到第三句的意思就是判斷兩個物件中String引用資料型別的兩個變數是否相等。

之後使用短路與 &&將這三句連線起來,如果這三句沒有一個是false,那麼說明這兩個物件中每個屬性的值是相同的。
那麼到現在我們就可以知道equals方法與 ==方法有什麼區別了:
總結:
在基本資料型別中, ==和equals方法沒有區別,都是比較的具體的值。
在引用資料型別中, ==比較的是兩個引用資料型別物件的地址是否相同,而equals方法比較的是兩個引用資料型別的物件中的每個屬性的實際的值是否相等。

相信小夥伴們都會了,別忘了點贊收藏哦。