目录
🍎写在前面
Java中的'=='是运算符,equals()是对象的方法
🍎Java中的数据类型
Java中的数据类型可以分为两类:
- 基本数据类型:byte,short,int long,float,double,char,boolean
- 引用数据类型:类、接口、数组等非基本类型
🍎基本数据类型和引用数据类型对于'=='运算符和equals()方法的使用规则:
-
对于基本数据类型的比较,只能使用'=='来判断其值是否相等。不能使用对象的equals()方法
-
对于引用数据类型(对象)来说,使用'=='运算符比较的是位于栈内存上的引用变量引用的(堆)对象的地址。
-
对于自定义类中的equals()方法,都是继承自Object类,而对于Object类中的equals()方法,在自定义类中没有进行手动覆盖的话,其实比较的还是引用变量位于栈空间上的地址
🍎Object对象中的equals()方法
对于Object类中的equals()方法,和运算符'=='没有区别,本质上比较的都是位于变量(普通变量和引用变量)栈内存空间上的地址。
public class StudentTestDrive {
public static void main(String[] args) {
Student s1 = new Student("小明",18,'男');
Student s2 = new Student("小红",19,'男');
Student s3 = new Student("小明",18,'男');
/*
==比较的是引用变量位于栈空间上的地址值,s1-s3的引用变量使用new关键字
在栈上开辟出了三块不同的内存空间,所以使用==匀速那副比较的三个对象的结果都是false
*/
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//false
System.out.println(s2 == s3);//false
/*
Student类中的equals()方法继承自object类,并没有进行重写,实际上和==运算符的
作用机制相同,比较的是变量在栈空间上的地址
*/
System.out.println(s1.equals(s3));//false
System.out.println(s1.equals(s2));//false
System.out.println(s2.equals(s3));//false
}
}
class Student {
private String name;
private int age;
private char sex;
public Student(String name,int age,char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//getter、setter、toString略
}
🍎String类中的equals()方法
在String对象调用equals()方法时,会发现两个String对象比较的是值而非栈空间上的地址。这是因为在String类中进行了equals方法的覆盖。即对Object类中的equals方法进行了覆写。
public class StringTestDrive {
public static void main(String[] args) {
String str1 = new String("Str");
String str2 = new String("Str");
/*
==运算符比较的是栈空间上的引用变量的地址,上边
使new关键字在栈空间上开辟了两块不同的内存空间,所以==运算符
的结果为false
*/
System.out.println(str1 == str2);//false
/*
String类中对继承自Object类中的equal()方法进行了覆写,
比较的是对象的内容。上边的两个String对象的内容相同,所以
equals()方法的返回结果为true
*/
System.out.println(str1.equals(str2));//true
}
}
🍎自定义类中equals()方法的覆写规则
- 判断传入的对象是否为当前调用equals()方法的对象所属类的同一类实例,如果不同,直接返回false
- 判断传入的对象是否为null,null没有对应的堆内存空间,无法进行equals方法的比较,直接返回false
- 判断传入的对象和调用equals()方法的对象的栈空间是否相同或者说二者是否是同一对象
- 将传入的Object对象向下转型,比较传入对象和调用equals()方法的对象的域,返回结果
public class StudentTestDrive {
public static void main(String[] args) {
Student s1 = new Student("小明",18,'男');
Student s2 = new Student("小红",19,'男');
Student s3 = new Student("小明",18,'男');
// System.out.println(s1.equals(s3)); //对equals()方法覆盖前输出false
System.out.println(s1.equals(s3));//true,覆写后的equals方法比较对象的每个域
System.out.println(s1.equals(s2));//false
}
}
class Student {
private String name;
private int age;
private char sex;
public Student(String name,int age,char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
/**
* 覆写Object类中的equal方法,实现对象域的比较
* @param obj
* @return
*/
@Override
public boolean equals(Object obj) {
//此时equal()方法会有两个对象,this对象和传入的Object对象
//1.判断this和obj是否为同一类实例
if(!(obj instanceof Student)) {
return false;
}
//2.判断传入的Object是否为空
if(obj == null) {
return false;
}
//3.判断this和Object是否引用自同一个对象
if(this == obj) {
return true;
}
//判断对象的对应域是否相同
Student sTemp = (Student) obj; //多态的应用,对象向下转型,访问传入的obj对象
return this.age == sTemp.age &&
this.name.equals(sTemp.name) &&
this.sex == sTemp.sex;
}
//getter、setter、toString略
}