浅谈JAVA中'equals'与'=='的区别
Java中’equals’与’=='的区别是什么?
在JAVA中,’=='与’equals’的返回值都是一个boolean数据(布尔型),true 或者 false。
一、定义上的区别
- "=="是Java中的一个关系运算符
- "equals"是Object中所定义的一个方法
二、比较对象上的区别
- "=="可以对基本数据类型或非基本数据类型进行比较
- "equals"无法对基本数据类型进行比较,只能对类对象(非基本数据类型)进行比较
三、比较内容的区别
- "=="是对变量的值进行比较
- "equals"是对类对象变量的引用进行比较
关系运算符“==”是怎么比较的?
- 我们首先讨论基本数据类型变量中的值比较。
代码如下:
// 基本数据类型变量值比较
int a = 10;
int b = 20;
int c = 10;
System.out.println(a==b);
System.out.println(a==c);
上面这段代码的输出结果是 false 、true
Java中的基本数据类型有 byte、short、int、log、char、float、double、boolean八种基本数据类型。
基本数据类型的变量是将值直接存入变量之中。所以 a==b输出为false,很显然a的值为10而b的值为20。两者的值是不相等的。反之a==c输出为true,a与c的值10=10。
显然对于基本数据类型的“==”比较还是比较好理解的
- 接下来对非基本数据类型变量的值比较进行讨论
// 非基本数据类型变量值比较
String str1=new String ("你好");
String str2=new String ("你好");
System.out.println(str1==str2);
输出的结果为:false
可能有朋友会不明白,为什么比较的结果是false呢,str1与str2中不都是“你好”这个字符串吗?
我们前面说过,"=="比较是对变量的值进行比较的,而str1与str2都是一个String的类变量(非基本数据类型变量)。
在类变量中存储的是对象的引用,或者说类变量中的值是一个对象的引用(一个实例对象的内存地址)。
new String("你好"); 这句代码就是将String类进行实例化,同时返回实例化对象的引用(可以近似的理解为C/C++中的指针)。
所以str1与str2中,分别创建两个String对象,尽管他们的内容是相同的,但是是两个不同的对象,所以对象的引用也不相同。所以我们就知道了str1==str2 的结果是false
Object中的equals是怎么比较的?
我们通常使用对象1.equals(对象2);语句来比较两个类变量的引用是否相同、是否是通一个对象。
那equals()方法是怎么进行比较呢?
我们还是先来看一看Object中对equals();方法是如何定义的吧。代码如下:
// Object中equals()方法的定义
public boolean equals(Object obj) {
return (this == obj);
}
解释一下,this的值是当前对象的引用。
我们根据object中对equals方法的定义中可以知道,传入一个对象的引用,与当前对象的引用进行比较。随后返回比较的结果。我们可以看到在equals()方法中是通过“==”进行比较的(即对值进行比较;this的值是当前对象的引用,传入的参数的值也是一个对象的引用),比较两个对象的引用是否相同。
- 那我们仍然以String类为例子试一试结果会是如何呢?
// String类的equals比较
String str1=new ("你好");
String str2=new ("你好");
System.out.println(str1.equalse(str2));
输出结果为:true
有没有感觉到不对劲呢?按照之前的逻辑这个输出结果不应该是false吗。str1与str2存储的是两个不同的引用,当str1调用equalse()方法比较时,也是用两个引用进行比较呀,怎么会返回true呢?当时我自己也觉得很奇怪,于是查看了str1.equalse(str2)方法的实现代码。
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类对Object中equalse方法进行了重写,根据代码分析我们可以知道其重写后的逻辑
- 当前对象的引用与传入对象引用进行比较 ,相同的话返回true。反之执行下一步
- 通过
anObject instanceof String语句判断,anObject是不是String类的实例化对象。不是的话返回false,反之执行下一步 - 判断两个对象的长度是否一致,若长度不一致则返回false。反之执行下一步
- 最后就是进行字符串的比较了
String重写了equalse方法后,在String类对象使用equalse时不再是判断两个对象的引用是否相同,而且是变成了判断两个对象引用中的值 (两个字符串)是否相等。