对于我们初入编程的小白来说,你可能有这样的疑问:equals()和 == 有什么区别呢?为什么有的时候,使用==或equals结果一样,但有的时候又不一样呢?
1.对于 == :
(1)如果比较的两个变量是基本数据类型(Byte,short,int,long,double,float,boolean,char)的话,不管数据类型是否相同,值相等则为true。
int a = 10;
double b = 10.0;
float c = 10;
char d = 'C';
char e = 67;
byte f = 10;
System.out.println(a == b); //true
System.out.println(a == c); //true
System.out.println(a == f); //true
System.out.println(d == e); //true
注意:boolean类型不可以进行比较,因为它只有true和false两种结果,不能用==和值进行比较
(2)如果比较的两个变量是引用数据类型,==比较的是两者的地址是否是同一个地址。
public static void main(String[] args) {
String name1 = "小王";
String name2 = "小张";
String name3 = "小张";
System.out.println(name1 == name2); //false
System.out.println(name2 == name3); //true
}
在创建name1变量时会在常量池中存放“小王”,创建name2变量时会存放“小张”,两者地址不同,则为false;创建name3的时候,发现在常量池中已经存在了,则name3和name2共同指向“小张”,则地址相同,则为true。
public class Students {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Students() {
}
public Students(String name) {
this.name = name;
}
public static void main(String[] args) {
Students s1 = new Students("小明");
Students s2 = new Students("小明");
System.out.println(s1 == s2); //false
}
}
那么这里内容相同,为什么用==比较后却为false呢?
因为这里是创建了两个Students类型的对象,对象是存放于堆内存中的,系统会为每一个对象分配一个内存地址,所以这里的s1和s2是指向两个不同的地址,则为false
2.对于 equals():多应用于比较两个对象的属性
equals()方法是属于Object类中的常用方法,如果子类没有重写equals()方法,那equals()方法和==相同,比较的是地址;该方法是这样写的:
public Boolean equals(Object o); 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同则为false
举例说明:
public class Students {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Students() {
}
public Students(String name) {
this.name = name;
}
public static void main(String[] args) {
Students s1 = new Students("小明");
Students s2 = new Students("小明");
System.out.println(s1.equals(s2)); //false
System.out.println(s1 == s2); //false
}
}
这里equals()比较两者的地址不相同,为false,那么既然 == 就能做的事情,为什么还要专门提供一个equals()方法呢?
因为我们在实际开发中,比较存储地址是否相同的地方并不是很多,更多的是为了比较存储的两者内容是否相同,为了便于理解,这里我手写了个重写equals()方法
public class Students {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Students() {
}
public Students(String name) {
this.name = name;
}
//自己重写equals(),自己定制规则,两个对象的内容一样就认为是相等的
@Override
public boolean equals(Object o){ //与任意类型的对象比较,用Object兼容性比较好
//1.首先判断o是不是Students类型,同类型才可以比较
if (o instanceof Students){ //判断对象与是否与o为同一类型
Students s = (Students)o; //必须进行强转,因为o里面没有name属性
//判断对象的内容是否一样
return this.name.equals(s.name);
//字符串的比较要用equals,字符串本身重写了equals,本身就是为了比较内容
}else
return false;
}
public static void main(String[] args) {
Students s1 = new Students("小明");
Students s2 = new Students("小明");
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s2); //false
}
}
当然,一般为了方便,你可以直接通过IDEA自动生成一个重写equals()方法,这样通过equals()方法直接比较两者内容是否相同。
父类equals()存在的意义:为了被子类重写,以便子类自己来定制比较规则。
需要注意的点:
(1)需要注意空指针异常,所以一般书写习惯用常量去比较变量,将不会为null的写在前面,可能为null的对象放在后面;如果两个对象都可能为null,可以用Java标准库中的工具类Objects来进行比较。
(2)equals()方法不能比较基本数据类型,当比较包装类时,需要先判断要比较的两个值类型是否一致。比如int(包装类:Integer)类型的值和long(包装类型:Long)类型的值不可比较,先判断出包装类类型错误则为false。