①==和equals的实质。
在JAVA中利用"=="比较变量时,系统使用变量在"栈"中所存的值作为比较的依据。
基本数据类型在"栈"中存的是其内容值,而对象类型在"栈"中存的是地址,这些地址指向"堆"中的对象。
java.lang包中的Object类有public boolean equals(Object obj)方法,它比较两个对象是否相等。
其它对象的equals方法仅当被比较的两个引用指向的对象内容相同时,对象的equals()方法返回true。
总之,"=="和"!="比较的是地址.也可认为"=="和"!="比较的是对象句柄;而equals()比较的是对象内容.或者说,,"=="和"!="比较的是"栈"中的内容,而equals()比较的是"堆"中的内容.
②==操作符。专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相当,只能用==操作符。
Java的基本数据类型为(char,byte,short,int,long,float,double,boolean)。
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(对内存),变量本身也占用一块内存,例如Object obj = new Object()变量obj是一个内存,new Object()是一个内存,此时,变量所对应的内存中存储的数据就是对象占用的那块内存的首地址。对于指向对象内存的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
equals方法。用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:
String a=new String("foo");
String b=new String("foo");
两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,他们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b即返回false,而这两个对象中内容是相同的,所以,表达式a.equals(b)将返回true。
在实际开发中,我们经常要比较传递进行来的字符串内容是否相等,许多人稍不注意就使用==进行比较了,这是错误的,有大量这样的错误。记住,字符串的比较基本都是使用equals方法。
如果一个类没有定义equals方法。它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
boolean equals(Object o){
return this==o;
}
这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也是比较两个变量指向的对象是否是同一个对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可以认为两个对象的内容是相同的。
示例代码:
public class Test {
public static void main(String[] args) {
Integer p = 1;
Integer q = 1;
Integer i = new Integer(1);
Integer j = new Integer(1);
if(p == q){
System.out.println("integer:p == q"); //实际结果
}else{
System.out.println("integer:p != q");
}
if(p.equals(q)){
System.out.println("integer:p.equals(q)"); //实际结果
}else{
System.out.println("integer:p.equals(q)");
}
if(i == j){
System.out.println("int:i == j");
}else{
System.out.println("int:i != j"); //实际结果
}
if(i.equals(j)){
System.out.println("integer:i.equals(j)");//实际结果
}else{
System.out.println("integer:!i.equals(j)");
}
String a = "abc";
String b = "abc";
String c = new String("abc");
String d = new String("abc");
if(a == b){
System.out.println("abc对象相等"); //实际结果
}else{
System.out.println("abc对象不相等");
}
if(a.equals(b)){
System.out.println("ab相等"); //实际结果
}else{
System.out.println("ab不相等");
}
if(c.equals(d)){
System.out.println("cd相等"); //实际结果
}else{
System.out.println("cd不相等");
}
if(c == d){
System.out.println("cd对象相等");
}else{
System.out.println("cd对象不相等"); //实际结果
}
}
}
中软国际电子政务部Jeff Chi总结,转载请说明出处。
----------------------------------------------------------------------------------
深入探讨equals:
===================
转自硅谷动力
equals方法的重要性毋须多言,只要你想比较两个对象是不是同一对象,你就应该实现equals方法,让对象用你认为相等的条件来进行比较.
下面的内容只是API的规范,没有什么太高深的意义,但我之所以最先把它列在这儿,是因为这些规范在事实中并不是真正能保证得到实现.
1.对于任何引用类型, o.equals(o) == true成立.
2.如果 o.equals(o1) == true 成立,那么o1.equals(o)==true也一定要成立.
3.如果 o.equals(o1) == true 成立且 o.equals(o2) == true 成立,那么
o1.equals(o2) == true 也成立.
4.如果第一次调用o.equals(o1) == true成立,在o和o1没有改变的情况下以后的任何次调用都成立.
5.o.equals(null) == true 任何时间都不成立.
以上几条规则并不是最完整的表述,详细的请参见API文档.对于Object类,它提供了一个最最严密的实现,那就是只有是同一对象时,equals方法才返回true,也就是人们常说的引用比较而不是值比较.这个实现严密得已经没有什么实际的意义, 所以在具体子类(相对于Object来说)中,如果我们要进行对象的值比较,就必须实现自己的equals方法.先来看一下以下这段程序:
public boolean equals(Object obj)
{
if (obj == null) return false;
if (!(obj instanceof FieldPosition))
return false;
FieldPosition other = (FieldPosition) obj;
if (attribute == null) {
if (other.attribute != null) {
return false;
}
}
else if (!attribute.equals(other.attribute)) {
return false;
}
return (beginIndex == other.beginIndex
& endIndex == other.endIndex
&& field == other.field);
}
|