一、equals()和==
1、equals()
java中所有的类都直接或间接继承Object这一基类,而equals()是Object类中的方法,所以equals()是每个类都拥有的方法,至于eqauls()方法的作用则需要看它的具体实现了。下面是Object中equals()方法的实现:
public boolean equals(Object obj){
return (this==obj);
}
从中可以看出,Object中的equals()方法用于比较两个对象的引用是否相等,是否指向的是同一个对象。
2、==
对于基本数据类型来说,==用于判断的两个变量的值是否相等。而对于引用类型来说,比较的是两个对象的引用是否指向同一个对象。
因此可以总结出,如果继承Object的类不对equals()方法进行重写的话,equals()的作用与==相同。但不同的是equals()不能用于基本数据类型,而==可以。
二、String中的equals()方法
String源码中的equals()是被重写过的,可以直接用于比较两个String中的对象的值是否相等,当然如果比较的两个String对象引用指向的是同一对象,结果也为true。下面来看看String中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.value;
while(n--!=0){
if(v1[i++]!=v2[j++])
return false;
}
return true;
}
}
return false;
}
举个例子:
public class Test5{
public static void main(String[] args)
{
String str1=new String("abc");
String str2=new String("abc");
System.out.println(str1.equals(str2));
System.out.println(str1==str2);
}
}
运行结果如下:
也许有人,在写下面两句语句:
String str1=new String("abc");
String str2=new String("abc");
时,这般写:
String str1="abc";
String str2="abc";
可能很多人觉得这两种方式没有什么不同,然而,结果是不尽相同的。
替换语句后的结果如下:
这主要是因为String pool(字符串常量池)机制的原因,这个我会在之后的博客解释。
二、重写equals()方法的模式
如果你想实现这样的效果:如果同一个类new的两个对象的成员属性相等的话,equals()方法结果返回true。那么我们可以根据上面String的equals()方法的模式重写equals()方法,一般模式如下:
public boolean equals(Object obj){
if(obj是否为所要判断的类的对象)
{
/*判断obj引用的类对象是否与激活该方法的类对象具有相同的值
。如果值相同则返回true,否则返回false。*/
}
else
return false;
}
示例:
public class Test {
private int a;
public String str;
public Test(int a,String str){
this.a=a;
this.str=str;
}
public boolean equals(Object obj){
if(obj instanceof Test){
Test test=(Test)obj;
return (test.a==a)&&(test.str.equals(str));
}else{
return false;
}
}
public static void main(String[] args)
{
Test t1=new Test(1,"abc");
Test t2=new Test(1,"abc");
System.out.println(t1.equals(t2));
}
}
来看一下这个if语句:
if(obj instanceof Test){
Test test=(Test)obj;
return (test.a==a)&&(test.str.equals(str));
}
这里,或许会有人疑惑:为什么需要下面这一句?
Test test=(Test)obj;
而不是直接
return (obj.a==a)&&(obj.str.equals(str));
个人认为具体的原因是:
在主方法调用equals()方法时,会执行如下语句的功能:
Object obj=t2;
也就是实参赋值于形参。在这个过程中,子类的对象引用转换为父类的对象引用,发生了面向对象语言中的“向上转型”。
而java的对象引用向上转型后,是不能调用子类独有的方法和属性的。所以我们必须将obj进行强制转换。
第二点会有人疑惑的点是:
语句return (test.a==a)&&(test.str.equals(str));
直接访问了Test类的私有变量a和str。
为什么可以这样访问呢?
答案是:只要方法所属类与对象的类型是相同的类,那么该方法就能访问对象的私有实例变量。
抱歉,有点啰嗦!
参考链接:
http://www.cnblogs.com/dolphin0520/p/3592500.html
参考文献:
《数据结构 Java语言描述 第3版》 –Michael Main