1、关于equals方法
equals方法是基类Object中的方法,因此对于所有的继承于Object的类都会有该方法。为了更直观地理解equals方法的作用,直接看Object类中equals方法的实现。该方法定义在Object类中,其源码如下:
/**
*Object.class
*/
public boolean equals(Object obj) {
return this == obj;
}
很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。
2、关于字符串的比较
先看如下代码:
public class Main {
public static void main(String[] args) {
String str1 = "abcd";//line 1
String str2 = new String(str1);// line 2
String str3 = "abcd";//line 3
String str4 = new String("abcd"); //line 4
String str5 = str1;//line 5
str5 = str5.concat("ef");//line 6
System.out.println(str1==str3);
System.out.println(str1==str2);
System.out.println(str2==str4);
System.out.println(str1==str5);
System.out.println(str1.equals(str3));
System.out.println(str1.equals(str2));
System.out.println(str2.equals(str4));
System.out.println(str1.equals(str5));
}
}
由上一篇博客Java基础之String可知后四行的打印结果为:true,true,true,fasle,对于最后一个false结果比较容易理解,str1的字符串内容为“adcd”,str5的内容为“abcdef”,两者显然不相同,故结果为false,而对于前三个结果,又该如何解释呢?
先看String类源码中的equals方法:
/**
*String.class
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof String) {
String s = (String) obj;
int i = value.length;
if (i == s.value.length) {
char ac[] = value;
char ac1[] = s.value;
for (int j = 0; i-- != 0; j++)
if (ac[j] != ac1[j])
return false;
return true;
}
}
return false;
}
看到这里我们应该明白了,原来String类对equals方法进行了覆写,用来比较指向的字符串对象所存储的字符串是否相等,从String类的equals方法可知,在equals方法中先进行引用对象的比较,如果两者指向的内存空间相同,及两者指向的为同一内存空间,字符串内容一定相同,直接返回true,如果两者指向的内存空间不同,在进行字符串内容的比较,如果内容完全相同,直接返回true,否则返回false。
3、关于其他类型
其他的一些类诸如Double,Date,Integer等,都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等。
4、关于关系操作符“==”
关于关系操作符“==”在《Java编程思想》中有这样一句描述:
关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系
先看如下代码:
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
int m=3;
int n=3;
System.out.println(m==n);
String str = new String("hello");
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1==str2);
str1 = str;
str2 = str;
System.out.println(str1==str2);
}
}
输出结果为 true false true;
- 对于基本数据类型的变量,变量直接存储的是“值”,因此在用关系操作符==来进行比较时,比较的就是 “值” 本身。
- 对于引用数据类型的变量,变量存储的是关联的对象在内存中的地址,str,str1,str2分别指向了一个String对象,此时str,str1,str2成为对象的引用,变量str,str1,str2中存储的是它们指向的对象在堆内存中的地址,并不是对象的“值”本身,也就是说并不是直接存储的字符串”hello”。因此在用==对str1和str2进行第一次比较时,得到的结果是false。因此它们分别指向的是不同的对象,也就是说它们实际存储的内存地址不同。
而在第二次比较时,都让str1和str2指向了str指向的对象,那么得到的结果毫无疑问是true。
5、总结
- 对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址;
- 对于equals方法,注意:equals方法不能作用于基本数据类型的变量,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
网友评论