首先我们先看看equals方法中的源代码,如下
public boolean equals(Object obj) {
return (this == obj);
}
从源代码我们可以看到,equals方法比较的内容在底层其实就是”==“,所以我们一般写程序都要复写equals方法,否则equals的比较和==一样。
一般覆盖equals方法的时候都会顺便覆盖hashcode方法。
-----------------------------------------------------------------------------------------------
一,对于基本数据类型变量
1, “==”一般用来比较两个值是否相等,一般用于比较基本数据类型,如a=10,b=10, 则 a==b,如果相等,==的比较久返回true。
2.,“equals" 不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。如
Boolean , Character , Byte, Shot, Integer , Longer , Float, Double 等包装类, 在这里”==“比较的是地址,看二者是否引用同一个堆内存空间,如果是则返回true,而”equals“ 是比较内容的。
例子:
int a1=1;
int a2=1;
Integer b1 =new Integer (1);
Integer b2 =new Integer (1);
a1==a2 这个是成立的
a1==b1 这个是不成立的.表达式的值为false ,它们是不同的数据类型(在jdk1.5以上版本中为true)
b1==b2 这个也是不成立的.表达式的值为false,虽然是相同的数据类型,但是它们是两个对象,==比较的是2个对象的地址,它们的地址是不相等的,内容相等都是1;
b1.equals(b2)==true 这个是成立的,表达式的值为true. 相同数据类型,两个对象,地址不同,内容相同, quals比较的是2个对象的内容,所以成立。
(a.equals(b),因为equals比较的是两个对象,所以a,b都不能为基本数据类型,否则会出编译错误。)(在jdk1.5以上版本中,b可以为基本数据类型,a不可以)
----------------------------------------------------------------------------------------
二,对于对象变量
1,”==“比较的是值,是引用变量的具体地址值,存放在栈内存中,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
2,“equals”操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
总结:对于对象变量,”==“,比较的是栈内存的内容是否相同,”equals“比较的是堆内存中的内容是否相同。
即 ”==“ 比较的是两个对象的地址,而”equals“ 比较的是两个对象的内容。
3,特殊之处,对于字符串对象,例如,
String s1 = "Monday";
String s2 = "Monday";
则 s1 == s2; 结果为true
我们可以看出,s1和s2指向的是同一个对象,原因是:
在JVM内,存在字符串池,其中保存着很多 String对象,并且可以被共享使用,因此它提高了效率.字符串池由String类维护,我们可以调用intern()方法来访问字符串池。当运用引号内包含文本创建对象时,所创建的对象是加入到字符串池里面的.如果要创建下一个字符串对象,JVM首先会到字符串池中寻找,是否存在对应的字符串对象,如果存在,则返回一个己存在对象的对象的引用给要创建的对象引用.如果不存在,才会创建一个新的对象,并返回一个新对象的对象引用给要创建的对象引用.以上这段话理解起来可能比较拗口.用代码理解就是str2和str1是两个对象引用,并指向了同一个对象.所以'=='返回的是true.
只有引号内包含文本创建对象才会将创建的对象放入到字符串池。String str = new String("abc")这种方法创建的字符串对象是不放入到字符串池的。所以,引号内包含文本创建对象的性能要比后来那种方法创建字符串对象的性能要好。
String str1 = "abc";
String str2 = "abc";
String str3 = str1+str2; //这种创建方式是不放入字符串池的.
String str4 = str1+"cd"; //这种创建方式是不放入字符串池的.
String str5 = "ab"+str2; //这种创建方式是不放入字符串池的.
String str6 = "ab"+"cd"; //这种创建方式是放入字符串池的.这种情况实际上是创建了1个对象,abcd"1个对象
String str7 = "abcd";
System.out.println(str1==str2); //返回ture
System.out.println(str6==str7); //返回ture
下面,我们再用几段代码来体验一下
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = "Monday";
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
}
}
编译并运行程序,输出:s1 == s2
说明:s1 与s2 引用同一个String 对象-- "Monday"!
再稍微改动一下程序,会有更奇怪的发现:
public class TestString {
public static void main(String[] args) {
String s1 = "Monday";
String s2 = new String("Monday");
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
if (s1.equals(s2))
System.out.println("s1 equals s2");
else
System.out.println("s1 not equals s2");
}
}
我们将s2 用new 操作符创建
程序输出:
s1 != s2
s1 equals s2
说明:s1 s2分别引用了两个"Monday"String对象
------- android培训、 java培训、期待与您交流! ----------