首先是这段代码:
public class test {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
if (s1 == s2){
System.out.println("s1 == s2");}
else{
System.out.println("s1 != s2");
}
if (s1.equals(s2)) {
System.out.println("s1 equals s2");
}else{
System.out.println("s1 not equals s2");
}
}
}
输出结果是:s1 != s2 和 s1 equals s2; 这个我可以理解,使用new操作符后,在堆内存中又新开辟了一块空间,s1和s2在堆内存中的值相同,但是引用的地址不同。但是在博客园的这篇文章看到下面这段代码:
public class test{
public static void main(String[] args)
{
test obj1 = new test();
test obj2 = new test();
if(obj1 == obj2){
System.out.println("obj1 == obj2");
}else{
System.out.println("obj1 != obj2");
}
if(obj1.equals(obj2)){
System.out.println("obj1 equals obj2");
}else{
System.out.println("obj1 not equals obj2");
}
}
}
输出: obj1 != obj2 obj1 not equals obj2
昨天晚上看了那篇文章的评论,把我自己的理解写出来,但是还是不是很清楚,我大意是这样的:
java当中所有类都继承自Object这个基类,在Object中的定义了一个equals方法,这个方法的初始化行为是比较对象的内存地址值(Object的equals方法使用==比较的),但在一些类库中这个方法被覆盖掉了,比如String, Interger, Date这些类中equals有其自己的实现方法,String类继承自Object类,也继承了equals方法,但是重写了该方法,不再比较类在堆内存中的存放地址了,而是比较存在堆中的值。 ???
这个解释不知道对不对,望指教,还有,关于obj1 not equals obj2你们是怎么看的??
大家讲道理2017-04-17 13:54:08
==
比較就不用說了,任何情況下都是比較記憶體位址。 equals
比較,是一個方法調用,預設的實作(Object
類別)是使用了==
:
public boolean equals(Object obj) {
return (this == obj);
}
第一段碼:
比較的是String
對象,而String
類別覆寫了equals()
方法,比較的是字串內容,所以輸出了s1 equals s2
。
這個你理解的沒有問題!
第二段程式碼:
比較的是test
對象,test
類別沒有覆寫equals()
方法,所以還是預設比較記憶體位址,從而輸出了obj1 not equals obj2
。
PHP中文网2017-04-17 13:54:08
在下以為應該先拋開程式碼實現,直接看 equals 方法存在的意義—--對比物件與物件是否相同。
那麼問題來了,物件與物件怎樣才算相同呢? 這個就該由物件所屬的類別的作者來決定了,也只有他才能決定其創造的類別的實例應該如何對比相同。
String的作者是誰不知道,但你也同意他的 equals 實作吧?字串對比字串,就該對比字元序列是否相同。
至於 test ,它的作者是題主你,而你沒有定義該如何對比test對象,但卻調用了 equals 想要對比它。此時會有個什麼結果? 只能是 test 這個類別的父類的 equals 結果唄,預設的父類是 Object 類,@ch_gilbert 已經說明了~
阿神2017-04-17 13:54:08
equals 取決於具體的實作
public class A{
private String color;
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public boolean equals(Object obj){
if (obj == null)
return false;
if (this == obj)
return true;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (color == null) {
if (other.color != null)
return false;
} else if (!color.equals(other.color))
return false;
if (weight != other.weight)
return false;
return true;
}
}
伊谢尔伦2017-04-17 13:54:08
你說的真複雜,好歹是看完了,應該是正確的理解
我貼一下Stirng.equals方法的原始碼,很明顯。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
==的比較,你可以理解,equals
說白了不就是個方法麼?具體怎麼實現的就是怎樣的結果,何必糾結呢?
假設equals這麼寫
怎麼樣,==不同,就看如果是「111111」才回傳true。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
if (anotherString.equals("111111")) {
return true;
}
}
return false;
}
這麼說明白了嗎? equals
這東西只是一個方法而已!因為Object
裡面有,其他的Class
都繼承它,所以看上去特殊點。