先说”==”:
对于基本数据类型 (byte,short,char,int,long,float,double,boolean)的变量”==”比较的是两个变量的值是否相等。
比如:int a = 3; int b = 3; a==b;返回就是true
对于引用类型,则比较的是该变量所指向的地址.
拿我们最常用的String型来举例:
比如:String a = “abc”; String b = “abc”;
因为字符串在程序中用的特别多,所以java对字符串的操作进行了优化,在这种情况下 字符串直接赋值给变量,该字符串会进入到常量池中,当第一次将 “abc”赋值给a的时候,会去常量池中找看有没有”abc”这个字符串,如果有的话,就将a指向该字符串在常量池中的地址,如果没有则在常量池中创建,第二次赋值 将 “abc”赋值给b的时候同样去常量池中找”abc”这个字符串,然后将他的地址赋值给b.
所以我们在做 a==b操作的时候返回的为true
再来看另一种情况:String a = new String(“abc”) ; String b = new String(“abc”);
这种情况下我们在做 a==b操作的时候返回的为false。
当我们 使用 String a = new String(“abc”)创建一个字符串对象时在内存里面是这样分配空间的,首先会去常量池中找”abc”如果找到了再创建一个”abc”对象存到堆中,并且他的值指向堆中的”abc”,如果没有找到则先在常量池中创建”abc”, 再在堆内存开辟一块内存空间创建”abc”,并且他的值指向堆中的”abc”。
再来看”equals”:
Equals方法是在Object类中定义的,所有的类都继承于Object类,所以所有的类都有equals方法。
我们来看看equals方法的源码:
public boolean equals(Object obj) {
return (this == obj);
}
可以看到在Object类的equals方法中也是用的”==”来进行比较,所以引用类型在进行比较时使用equals比较的是地址,它和”==”是等价的
字符串虽然也是引用类型,但是它比较特殊,它比较的是字符串的内容
原因就是 String类型对equals方法进行了重写。我们来看源码:
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;
}
从源码我们可以看出,在String的equals方法中对字符串的字符进行了逐一比较如果都相同则返回true.所以对于String中的equals方法比较的是两个字符串的内容对于:
String a = new String(“abc”) ; String b = new String(“abc”);
由于a和b的内容相同,返回true.
总结:
- 对于基本类型==比较的是值,对于引用类型比较的是地址
对于引用类型,equals比较的也是地址和“==”等效,字符串比较特殊,它比较 比较的是两个字符串的内容