先来看以下代码
public static void main(String args[]) {
int i1 = 1; int i2= 1;char c1 = 'a'; char c2 = 'a';
String s1 = new String("Hello"); String s2 = new String("Hello");
System.out.println(i1 == i2);
System.out.println(c1 == c2);
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
输出结果:
true
true
false
true
分析:
- 对于基础数据类型(boolean,byte,char,short,int,float,double,long),“==”比较的是他们的值。如i1和i2,c1和c2。
- 对于复合数据类型,“==”比较的是他们在内存中的存放地址。s1和s2虽然内容相同,但是他们指向的对象地址不同。
- equals默认(Object类中)是比较对象的内存地址,但是一些类库中重写了equals方法,如:String、Integer和Date类,应该按照重写的方法进行比较。一般都是比较对象的内容
局部变量s1和s2是存放在栈内存中,而new出来的对象是放在堆内存中,s1和s2所指向的对象不同,地址不同,故s1==s2输出false,前面说equals方法默认也是比较地址,但为何输出true呢?因为:s1.equals(s2)处的equals不是Object类中的,而是String类中,String类中重写了Object类中的该方法,因此比较的是对象中的内容(Hello)。附上Object和String中equals方法源码:
//Object
public boolean equals(Object obj) {
return (this == obj);
}
//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;
}