01、对于 == 来说:
如果比较的是基本数据类型变量,比较两个变量的值是否相等。(不一定数据类型相同)
如果比较的是引用数据类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个地址值
测试基本数据类型:
int a = 20;
double c = 20.0;
char i = 20;
char j = 'A';
char m = 65;
boolean boo = true;
System.out.println(c==a);//true
System.out.println(a==i);//true
System.out.println(j==m);//true
System.out.println(boo==a);//编译不通过
其中, 布尔类型不能参与运算符==比较,
报以下错误:
Operator ‘==’ cannot be applied to ‘boolean’, ‘int’
测试引用数据类型:
public class Student {
private int age;
private String name;public Student(int age, String name) {
this.age = age;
this.name = name;
}
public static void main(String[] args) {
Student stu1 = new Student(11, "张三");
Student stu2 = new Student(11,"张三");
System.out.println(stu1==stu2);
}
}
分析:
虽然两个对象的属性值都相等。
但是系统会为每一个new的对象分配内存地址值。(存放在堆中)
两个对象的引用指向不同的地址值,所以结果为false。
String str = new String("hello");
String str2 = new String("hello");
System.out.println(str.equals(str2));//true
使用了 equals
方法来比较这两个字符串对象的内容,因为字符串类 String
已经重写了 equals
方法,它会比较字符串的内容是否相等。在这种情况下,输出将会是 true
,因为 str
和 str2
的内容都是相同的。
这表明在 Java 中,字符串对象的内容相等可以通过 equals
方法来比较,而不是使用 ==
比较它们的引用地址。
String str = "hello";
String str2 = "hello";
System.out.println(str==str2);//true
分析:
str2创建对象的时候发现常量池中已经存在 “hello”,这时不需要创建新的对象直接将str2引用指向"hello",这样str和str2引用指向同一个地址值,所以结果为true。
对于 equals 来说:
如果类中重写了equals方法,比较内容是否相等。
String、Date、File、包装类都重写了Object类的equals方法。
如果类中没有重写equals方法,比较地址值是否相等(是否指向同一个地址值)。
Student stu1 = new Student(11, "张三");
Student stu2 = new Student(11,"张三");
System.out.println(stu1.equals(stu2));//false
既然equals比较的是内容是否相同,为什么结果还是false呢?
回顾知识:
在Java中我们知道任何类的超类都是Object类,Student类也继承Object类。
查看Object类中的equals方法也是 == 比较(也就是比较地址值),因此结果当然是false
public boolean equals(Object obj) {
return (this == obj);
}
在 equals
方法内部,首先会检查 this == obj
,也就是检查当前对象和传入的对象是否是同一个引用(内存地址是否相同)。如果是的话,它们一定相等,直接返回 true
。
既然这样我们如何保证两个对象内容相同呢?
这里就需要我们去重写equals方法?
@Override
public boolean equals(Object obj){
if (this == obj){
return true;
}
if (obj instanceof Student) {
Student stu = (Student)obj;
return this.age == stu.age && this.name.equals(stu.name);
}
return false;
}//true
更加全面的重写equals方法,我们可以自动生成一下
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
使用 instanceof
运算符检查 obj
是否是 Student
类型的对象。这是为了确保我们可以将 obj
转型为 Student
类型,以便比较它们的属性。
如果 obj
是 Student
类型,就将其转型为 Student
对象,并且比较两者的 age
和 name
属性是否相等。如果相等,返回 true
,表示两个对象相等。否则,返回 false
,表示两个对象不相等。