点开这篇文章的同学们大概是已经发现了JAVA中的== 与其他语言中的 == 有不一致的地方了。下面我们就来说说在JAVA中怎么比较两个参数是否相等。
面试题:JAVA中==和equals的区别
答:
- == 应用在基础数据类型中,比较的是他们的值,应用在引用数据类型中比较的是存储对象的内存地址;
- 基础数据类型中不能使用equals方法,只有引用数据类型才可以使用equals,因为Object是所有类的始祖,Object中的equlas方法本质其实还是==,所以如果不重写equals方法,那么它其实跟==一样是比较存储对象的内存地址。而我们通常会重写equals方法,让他变成值比较。比如String,Integer中就重写了equlas方法。
先了解下JAVA中的数据类型
JAVA中的数据类型有两种,分别是基本数据类型和引用数据类型
基本数据类型
一共八种,分别是:byte,short,int,long,float,double,boolean,char
基本数据类型变量名指向具体的值
引用数据类型
一共三种,分别是:类,数组,接口(如String,String[],Integer等)
引用数据类型变量名指向存储对象的内存地址
接下来回归到我们原来的问题,先看“==”是怎么处理基本数据类型,引用数据类型的比较的
==
上面我们已经了解到了,基本数据类型变量名指向值,而引用数据类型变量名指向存储对象的地址
所以对于基本数据类型,==比较的就是值,而对于引用数据类型,==比较的就是 存储他们的地址。
代码示例
int a = 1;
int b = 1;
boolean ab = a == b;
System.out.println(ab) // 打印出来 ab为true,比较的是变量a,b的值
Integer c = 1;
Integer d = 1;
Integer e = new Integer(1);
boolean cd = c == d;
boolean ce = c == e;
System.out.println(cd) // 打印出来 cd 为true,c,d 指向的是同一个引用,所以地址相同
System.out.println(ce ) // 打印出来 cd 为false,c,e指向的是不同的引用,所以地址不同
equals
Object类是Java中所有类的始祖,JAVA中每个类都扩展了Object,在Object中equals就跟==一样,但是很多类,比如String,Integer这些都是重写了equals方法的
下面我们看下Object,String类中equlas部分的源码
// Object 类中的equlas源码,从return语句可看出本质其实就是==
public boolean equals(Object obj) {
//从这可以看出其实就是用了==
return (this == obj);
}
比如要比较String a = “aaa”,String b = "bbb"是否相等,a.equals(b)
// String类中的equlas源码
public boolean equals(Object anObject) {
// 先比较两个参数的引用是否一样,如果一样那肯定相等,return true即可,不需要再比较
if (this == anObject) {
return true;
}
// 如果两个参数的引用不一致,比较他们的值
// 先判断要比较的参数是否是String类型,如果不是肯定不相等,如果是,则继续执行
if (anObject instanceof String) {
String anotherString = (String)anObject;
// 此处value 是个全局变量,char[]类型的,存储的是equlas左边的变量(a.equals(b),value 存储的就是a的字符)
// n = 字符串a的长度
int n = value.length;
// 字符串a的长度和字符串b的长度一致,则继续,否则不相等
if (n == anotherString.value.length) {
// 字符串a赋值给v1
char v1[] = value;
// 字符串b赋值给v2,anotherString.value把字符串b转换为了char[] 类型
char v2[] = anotherString.value;
int i = 0;
// 循环比较两个字符数组中每个字符是否相等,若存在不相等则肯定不相等,反之相等
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}