《深入理解 == 与 equals ():Java 中对象比较的奥秘》
目录
一、== 运算符
1. 使用范围
2. 比较规则
二、equals() 方法
1. 使用范围
2. 具体使用及重写与否的区别
三、总结
一、==
运算符
1. 使用范围
==
运算符的使用范围非常广泛,它既可以用于基本数据类型,也可以用于引用数据类型。
2. 比较规则
- 基本数据类型:当
==
用于比较基本数据类型时,它的作用是判断两个数据值是否相等。例如,比较两个整数、两个浮点数、两个字符等的数值是否相同。
下面是一个简单的示例:
int num1 = 5;
int num2 = 5;
System.out.println(num1 == num2); // 输出:true,因为num1和num2的值都是5
- 引用数据类型:当
==
用于引用数据类型时,它比较的是两个引用变量的地址值是否相等。也就是说,它在判断两个对象是否指向了堆空间中的同一个对象实体。
考虑以下示例
class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
Person person1 = new Person("Alice");
Person person2 = new Person("Alice");
Person person3 = person1;
System.out.println(person1 == person2); // 输出:false,person1和person2指向不同的对象实体
System.out.println(person1 == person3); // 输出:true,person3和person1指向同一个对象实体
在上述代码中,虽然 person1
和 person2
的 name
属性值相同,但它们是通过 new
关键字分别创建的两个不同的对象,所以 ==
比较的结果为 false
。而 person3
直接指向了 person1
所指向的对象,所以 person1
和 person3
用 ==
比较时结果为 true
。
二、equals()
方法
1. 使用范围
equals()
方法只能使用在引用数据类型上。
2. 具体使用及重写与否的区别
- 未重写
equals()
方法(默认情况):对于自定义的类,如果没有重写Object
类中声明的equals()
方法,那么调用该方法时,实际上就是在比较两个对象的引用地址是否相同。(或比较两个对象是否指向了堆空间中的同一个对象实体)。
以下是一个示例来说明未重写 equals()
方法时的情况:
class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
}
Book book1 = new Book("Java核心技术", "Cay Horstmann");
Book book2 = new Book("Java核心技术", "Cay Horstmann");
System.out.println(book1.equals(book2)); // 输出:false,因为没有重写equals()方法,比较的是引用地址
在这个例子中,book1
和 book2
虽然具有相同的书名和作者,但由于 Book
类没有重写 equals()
方法,所以 equals()
比较的结果是 false
,因为它们指向不同的对象实体。
- 重写
equals()
方法:在实际开发中,针对于自定义的类,常常会判断两个对象是否equals()
,而此时主要是判断两个对象的属性值是否相等。所以我们通常要重写Object
类中的equals()
方法。
下面是重写 equals()
方法后的 Book
类示例:
class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass()!= o.getClass()) return false;
Book book = (Book) o;
return Objects.equals(title, book.title) && Objects.equals(author, book.author);
}
}
Book book1 = new Book("Java核心技术", "Cay Horstmann");
Book book2 = new Book("Java核心技术", "Cay Horstmann");
System.out.println(book1.equals(book2)); // 输出:true,因为重写了equals()方法,比较的是属性值
在上述重写后的代码中,我们首先判断传入的对象是否就是当前对象(通过 if (this == o) return true;
),然后判断传入对象是否为 null
或者是否属于同一类(通过 if (o == null || getClass()!= o.getClass()) return false;
)。如果都满足,就将传入对象强制转换为 Book
类(因为我们知道它是同一类了),最后比较两个对象的属性值是否相等(通过 Objects.equals(title, book.title) && Objects.equals(author, book.author)
)。这样,当我们比较 book1
和 book2
时,就会根据它们的属性值来判断是否相等,结果为 true
。
对于 String
、File
、Data
和包装类等,它们都已经重写了 Object
类中的 equals()
方法,用于比较两个对象的实体内容是否相等。例如:
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1.equals(str2)); // 输出:true,因为String类重写了equals()方法,比较的是字符串内容
三、总结
通过以上的分析和示例,我们可以清晰地看到 ==
运算符和 equals()
方法在对象比较中的不同作用。==
主要用于判断基本数据类型的值是否相等以及引用数据类型的引用地址是否相等;而 equals()
方法在未重写时也比较引用地址,但在重写后通常用于比较自定义类的对象属性值是否相等。在实际开发中,我们要根据具体需求正确使用这两种比较方式,特别是对于自定义类,要根据是否需要比较属性值来决定是否重写 equals()
方法。希望这篇博客能够帮助大家更好地理解和掌握 ==
与 equals()
的区别,在编程和面试中都能应对自如。