基本數據類型:因爲基本數據類型沒有引用對象,所以 “==” 的效果就是比較值是否相同,基本數據類型沒有 equals 方法
引用數據類型:“==” 和 equals 兩者都是比較引用的對象是否相同
爲什麼我們在網上會看到說:雙等比較引用,equals比較值呢?
那是因爲equals被重寫了,重寫之後的效果就是比較值是否相等,那些例子都是用String類型之間進行比較的,String內部默認重寫了equals方法,所以纔有了以上的說法
如下是equals的源碼,可以看到equals的內部實現就是 “==”
public boolean equals(Object obj) {
return (this == obj);
}
如下是String內部重寫equals的源碼
- String內部重寫了equals方法,重寫後的效果就是比較兩個對象的值是否相等
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;
}
對應引用數據類型來說,可以這樣記:
-
如果equals沒有被重寫,兩種比較是相同的
-
如果equals被重寫了,那麼兩種比較自然不同
-
String內部默認重寫了equals方法,所以:”==“ 比較引用,equals 比較值
String測試
(”==“ 比較引用,equals 比較值)
直接定義兩個值相同的字符串進行比較
String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); // true
System.out.println(str1.equals(str2)); // true
在創建字符串的時候,會先創建一個字符串緩衝池
當創建str1時,先在字符串常量池中尋找有沒有對應“hello”的對象,如果沒有,就創建一個,然後將str1對象放入字符串常量池中,將str1的值“hello”放入常量池中
JDK1.7後:字符串常量池保存引用,常量池保存值
當創建str2時,先在字符串常量池中尋找有沒有對應“hello”的對象,發現str1對應的值和自己要創建的字符串值相同,就直接引用str1所引用的對象
所以
- str1==str2:兩者引用的對象相同,都是“hello”;
- str1.equals(str2)也相同:兩者的值相同
直接定義兩個值不同的字符串進行比較
String str1 = "hello";
String str2 = "hi";
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // false
- 兩者所引用的對象不同,所以 str1 == str2 肯定爲false
- 兩者的值也不同,所以下面的也是false
new兩個值相同的字符串進行比較
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true
在new一個對象的時候,不會從字符串緩衝池中尋找,而是直接開闢一個新的空間來創建一個新的對象,創建的對象也不會添加到常量池中
所以
- new了兩個對象,兩個對象的引用肯定不是同一個,雙等的比較爲false
- 但是兩個對象的值是相同的,都是“Hello”,所以equals的比較相同爲 true
new兩個值不同的字符串進行比較
String str1 = new String("Hello");
String str2 = new String("Hi");
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // false
- new了兩個對象,兩個對象的引用肯定不是同一個,雙等的比較爲false
- 兩個對象的值也是不相同的,所以equals的比較不同爲 false
直接定義一個字符串和new一個字符串進行比較(兩者值相同)
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true
- 因爲str2 new了一個新對象,所以和str1的引用不是同一個,雙等的比較爲false
- 但是兩者的值是相同的,所以equals的比較爲 true
直接定義一個字符串和new一個字符串進行比較(兩者值不同)
String str1 = "Hello";
String str2 = new String("Hi");
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // false
- 因爲str2 new了一個新對象,所以和str1的引用不是同一個,雙等的比較爲false
- 兩者的值是不相同的,所以equals的比較也爲 false
其它對象測試
(”==“ 比較引用,equals 也比引用)
首先創建一個實體類
class Person {
private int id;
public Person(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
new 兩個值相同的對象
Person person1 = new Person(12);
Person person2 = new Person(12);
System.out.println(person1 == person2); // false
System.out.println(person1.equals(person2)); // false
- 因爲equals沒有被重寫,所以兩種比較都是一樣的,都爲false
new兩個值不同的對象
Person person1 = new Person(12);
Person person2 = new Person(25);
System.out.println(person1 == person2); // false
System.out.println(person1.equals(person2)); // false
- 因爲equals沒有被重寫,所以兩種比較都是比較引用是否相同,和對象的值無關,所以都爲false
總結
基本數據類型:因爲基本數據類型沒有引用對象,所以 “==” 的效果就是比較值是否相同,基本數據類型沒有 equals 方法
引用數據類型:“==” 和 equals 兩者都是比較引用的對象是否相同
- equals 方法可以被重寫
- String內部默認重寫了 equals 方法,使其效果爲判斷兩者的值是否相等
- 創建字符串時,會先在字符串常量池中進行查找