嗯先铺垫一下Java中的相等问题,比较方法有equals和==,比较的方向有内容相等和地址相等。
1.equals:只能比较对象,比较对象地址是否相等;可以重写equals方法,比如String重写equals方法改为内容是否相等。
2.==:可以比较基础数据类型和对象,基础数据类型比较值是否相等,对象比较地址是否相等。
看一个经典的问题,String的equals问题。
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InstantiationException {
String ss= "test";
String ss1= "test";
String ss2= new String("test");
System.out.println(ss==ss1);
System.out.println(ss.equals(ss1));
System.out.println(ss==ss2);
System.out.println(ss.equals(ss2));
}
输出结果:
ss==ss1:true
ss.equals(ss1):true
ss==ss2:false
ss.equals(ss2):true
其实这个问题上“==”的使用一直是没有异议的,就是看String的地址是否相等。主要问题是equals的方法,很多博客在说的时候没有区分String和Object在使用equals方法的区别,这很容易产生误导(至少我很长一段时间就分不清equals的使用情况)。我们看一下String.equals()和Object.equals()的源码就很容易理解这个问题。
//String的equals方法
public boolean equals(Object anObject) {
//首先是object同样的比较方法,因为地址相等那么值肯定是相等的,也就没有必要进行下面的比较了
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;
}
//object 的equals方法
public boolean equals(Object obj) {
return (this == obj);
}
总结:我们看两个对象是否是同一个对象就是看内存地址是否相等。(重点说明一下这里说的不是对象是否相等)
这个不难理解,java中对象是存在java堆中,每new一个,就相当于新创建一个对象,系统就会分配一个存储对象的唯一地址,如果两个对象的地址是相同的那么这两个对象自然也就是同一个对象。