1.“==”比较的是对象或者基础数据类型的地址是否相同
给出例子:
Son son1 = new Son();
Son son2 = new Son();
System.out.println(son1==son2);
很明显,结果是false。解释为:运行时,两个实例对象分别加载到堆的不同地址。
再来看:
int a = 3;
int b = 3;
System.out.pritln(a==b);
我们都知道结果是true,但是原因是什么?这要深入到JVM的数据内存结果原理,这里不深入,只给出结论:a与b都存放在栈中。基本数据变量存放在栈时,如果值相同的话,它们的引用就会指向相同的地址。
2.“equals”比较的内容要根据对象的equals方法怎么写
听起来像废话,但确实是这样,不同对象有不同的equals实现。
这里给出常用情况:
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;
}
先给出结论:String比较的是对象内容是否一样。
第一个if很明显就是 比较两个String引用指向的地址是否一样。
大家疑惑肯定是第二个,为什么会有第二个if,怎么感觉有点多余啊?
这并没有多余。String有两种定义方式:
1).String str1 = "test";
2).String str2 = new String("test");
这两种定义所导致的内存存储有点不一样。这要涉及到常量池的内容,str1定义会产生一个或者0个对象。如果你在str1前像这样String str1bf = "test";的话那么就不会在常量池产生新的对象,而是直接指向已经存在的"test";
第二种会产生至少一个对象,首先内存的堆里面肯定会产生一个对象。另外,跟上面一样,当常量池存在“test”这个对象是,就不会在常量池产生新的“test”对象。反之,就会。
现在我们就明白了。第二个if所比较的是对象的内容是否一样(即使内存地址不一样,例如上面的str1与str2比较)。
其实第一if比较的虽然是地址的大小,但是实际上也可以看作比较的内容是否一样。地址都一样了,内容肯定一样啦。
Integer:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
这个所比较的也是内容是否一样。
自定义类:
public boolean equals(Object obj) {
return (this == obj);
}
自己
定义的类默认是继承了Object对象的,默认比较的是地址。
但一般都建议要重写equals()方法,使其比较的是内容。毕竟有了"=="这个比较地址异同的存在。你再用equals来比较地址的话就重复了。
总结一下:
1)“==”比较的是地址的异同
2)“equals”一般比较的是内容的异同
3)自定的类,"equals"默认比较的也是地址的异同,一般建议重写。