-
==是运算符,而equals是基类Object的一个方法。
-
对于基本数据类型而言,比较的是值的内容(例如:int、float等),其实本质上也是比较的是地址。基本数据类型都是存在栈里的,int a=1;当int b=1时,JVM会在栈中找有没有3这个内容,如果有就将b指向栈内存的地址,这样一来,a与b的地址相同,所以 ab输出true
而对于引用数据类型来讲,比较的是堆内存的地址,下面我们来看看下面代码:
String str1="Hello" ;
String str2="Hello";
String str3=new String("Hello");
String str4=new String("Hello");
System.out.println(str1==str2);
System.out.println(str3==str4);
输出结果依次是 true、false。我们先来了解一下栈内存中存放的是引用对象名称,而堆内存中存储的是真正的数据内容。第一二行字符串在常量池中存储,JVM会先在常量池中查找是否有相同内容的字符串,如果有,就将栈中的引用直接指向该字符串,如果没有,则在常量池中生成一个字符串,再将栈中的引用指向该字符串。而第三四行代码是在堆上面开辟了一个空间,每实例一次就new一次,str3和str4分别指向不同的地址,所以用==进行比较时,输出false。
- 一般对于引用数据类型的内容比较用equals,但是必须对equals方法进行覆写。
equals是基类Object的一个方法,所有引用对象都可以使用,但是Object中equals方法的只是地址的比较,源码如下
public boolean equals(Object obj) {
return (this == obj);
}
用下面这段代码说明一下:
Person per=new Person("张三");
Person per1=new Person("张三");
//true
System.out.println(per.equals(per));
//false
System.out.println(per.equals(per1));
String str=new String("Hello");
String str1=new String("Hello");
//true
System.out.println(str.equals(str));
//true
System.out.println(str.equals(str1));
输出结果依次是true、false、true、true . 为什么都是引用类型调用的Object的equals,输出结果却不一样。这是因为String类型覆写了equals方法,不仅仅比较的是地址还对内容进行了比较,内容相等就返回true。源码如下:
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;
}
当我们自定义类在用equals方法对引用数据类型比较时,必须覆写。