咱們在學習Java的時候,看到==、equals()就認爲比較簡單,隨便看了一眼就過了,其實你並無深刻去了解兩者的區別。這個問題在面試的時候出現的頻率比較高,並且據統計有85%的人義正詞嚴的答錯。因此理解==與equals()的區別頗有必要。java
==可使用在基本數據類型變量和引用數據類型變量中。面試
一、若是比較的是基本數據類型變量:比較兩個變量的數值是否相等(數據類型不必定要相等,只看值,由於會類型自動提高!);數組
二、若是比較的是引用數據類型變量:比較兩個對象的地址值是否相等。ide
下面看一下案例:學習
public class Test { public static void main(String[] args) { int a=10; int b=10; double c=10.00; System.out.println(a==b);//true System.out.println(a==c);//true String str1="123"; String str2="123"; System.out.println(str1==str2);//true String str3=new String("123"); String str4=new String("123"); System.out.println(str3==str4);//false } }
結果爲:true、true、true、false。前面兩個爲true的結果很是容易理解,可是第三個爲true,第四個爲false,而它們都是String引用類型,爲何不同呢?測試
分析緣由:this
對於8種基本數據類型(byte,short,char,int,float,double,long,boolean)的值而言,它們都是存儲在常量池中,而str一、str2的字符串 "123" 也一樣在常量池中,而一個常量只會對應一個地址,所以不論是再多的數據都只會存儲一個地址,因此全部他們的引用都是指向的同一塊地址,所以基本數據類型和String常量是能夠直接經過==來直接比較的。spa
而str三、str4分別在堆內存中建立的兩個對象,地址值天然就不相同了。code
equals()是一個方法,不是數據類型,因此他只適用於引用數據類型。對象
該方法主要用於比較兩個對象的內容是否相等。其實這樣的說法是不許確的。首先咱們來看看在Object類中定義的equals方法:
能夠看到,在Object類型的equals方法是直接經過==來比較的,和==是沒有任何區別的。
那麼爲何又要說equlas和==的區別呢?是由於全部的類都直接或間接地繼承自java.lang.Object類,所以咱們能夠經過重寫equals方法來實現咱們本身想要的比較方法。
咱們建立一個Person類來測試,先不重寫父類的equals()方法:
public class Test { public static void main(String[] args) { Person person1=new Person("菜徐坤",21); Person person2=new Person("菜徐坤",21); System.out.println(person1.equals(person2)); } } class Person{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } }
毫無疑問,輸出的結果確定是false,由於沒有重寫父類的equals()方法,從而調用了父類的,而父類的equals()方法是用==判斷的。
而後咱們重寫父類的equals()方法:
public class Test { public static void main(String[] args) { Person person1=new Person("菜徐坤",21); Person person2=new Person("菜徐坤",21); System.out.println(person1.equals(person2)); } } class Person{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (age != person.age) return false; return name != null ? name.equals(person.name) : person.name == null; } }
重寫以後輸出就是true了,由於比較的對象的內容。
實際上,像String、Date、Math、File、包裝類等大部分類都重寫了Object的equals()方法。重寫之後,就不是比較兩個對象的地址值是否相同了,而是比較兩個對象裏面的內容是否相等。
下面咱們來看一下String類重寫的equals()方法:
* @see #compareTo(String) * @see #equalsIgnoreCase(String) */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof 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; }
能夠看到重寫的方法內用char[] 數組進行一個一個的比較,並非用==進行比較,。
咱們在重寫equals()方法時必需要遵循以下幾個規則:
對於上面幾個規則,咱們在使用的過程當中最好遵照,避免出現意想不到的錯誤。
一、==比較的數值是否相等和對象地址是否相等。
二、equals()方法比較的對象內容是否相等(前提是重寫了父類的方法)。
三、通常除了自定義的類除外,大部分可以使用的類都重寫了equals()方法。