一:“==”的用法
来看下面的代码:
// 基本数据类型
int n =3;
int m=3;
System.out.println(n==m);
//引用类型
String str = new String("abc");
String str1 = new String("abc");
String str1 = new String("abc");
System.out.println(str1==str2);
str1 = str ;
str2 = str;
System.out.println(str1==str2);
输出结果为true,false,true。
在解释之前,我们先介绍Java中的8大基本数据类型
- 整形类: byte、short、int、long
- 浮点型: float、double
- 字符类: char
- 布尔类型: boolean
这几种都是基本类型,“==”比较基本类型的变量时比较的是赋予变量的值,运行下面的语句:
int n = 3;
int m = 3;
两个int类型的变量被赋予的值都是3。所以第一个输出语句中”n==m"判定结果为true。
对于非基本类型的变量,就是引用对象类型的变量,比如上例中的“str”变量,其存储的不是一个“值”,而是new出来的对象在内存中的地址(JVM虚拟机内存)。此时"==“比较的是两个变量在内存中的地址。
比如下面这个语句:
String str1;
该语句此时只是声明了一个String引用类型的变量,并没有任何对象指向它,接下来可以通过一个new语句创建一个String类型的对象,然后与之前的对象变量str1进行绑定。
上例代码中,String类型的变量str1和str2都用了一个new语句,此时在内存中建立的是两个对象,在内存中的地址不同,他们就像两个双胞胎,是两个不同的实例。所以第二个输出语句中”str1==str2"判定结果为false。
接下里继续运行下面的语句:
str1 = str;
str2 = str;
这两个语句使str1和str2都指向了str指向的地址,所以此时变量str1和变量str2指向的地址相同(准确来说是三者都相同,还有str),所以第三个输出语句中“str1==str2"的判定结果为true。
二:”equals"的用法
equals方法是基类(父类)Object中的方法,因此对于所有的继承于Object的类都会有该方法。来看一下源代码中Object类的equals方法的实现:
public boolean equals(Object obj){
return(this==obj);
}
显而易见,在基类Object类中,equlas方法比较的是对象在内存中存储的地址,与“==”相似,但无法比较基本类型的变量。
看到这儿可能会有觉得既然Obiect类中的equals方法与“==”类似,而且只能比较引用类型的变量,那为什么还要用equals方法?老师上课还要讲这个,咱也不知道为啥要讲这个“没用”的方法,咱也不敢问。。。
但是细心的会发现刚刚看的源码是基类Object类中的equals方法的实现,基类中的方法是可以被Java中的很多类进行重写的。
来一起看下面这个代码:
public static void main(String[] args){
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));
}
这里的运行结果为true。
因为变量str1和str2都是String类型的变量,他们所调用的equals方法是String中重写的equals方法。
来看一下String类的equals方法的源码:
public boolean equals(Object anObject){
if(this==anObject){
return false;
}
if(anObject instanceof String){
String anotherString = (String)anObject;
int n = value.length;
if(n==anotherString.value.length){
char1 v1[]=value;
char2 v2[]=anotherString.value;
int i=0;
while(n-- !0){
if(v1[i]!=v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
可以看出,String类对equals方法重写后,此时的equals方法比较的是指向的两个字符串对象所存储的字符串是否相等。
其他的一些类比如Double,Date等,也对equals方法进行了重写,用来比较指向的对象所存储的内容是否相等。
最后总结一下:
一:对于“==”,如果比较的是两个基本类型的变量,那比较的就是他们两个的值;如果比较的是对象引用类型的变量,那比较的就是他们在存储在内存中的地址。
二:对于“equals”方法,首先注意它不可以比较两个基本类型的变量。如果没有对它进行重写,那比较的就是所指向的对象的地址。如果像是String类、Integer类等重写了equals方法,那比较的就是所指向的对象的内容。