在 Java 里,==
和equals
方法都用于比较,但它们的用途和比较方式存在明显差异,下面为你详细介绍:
1. 基本数据类型的比较
对于byte
、short
、int
、long
、float
、double
、char
、boolean
这些基本数据类型,只能使用==
进行比较,比较的是它们的值。
int a = 5;
int b = 5;
System.out.println(a == b); // 输出:true
double x = 3.14;
double y = 3.14;
System.out.println(x == y); // 输出:true
char c1 = 'A';
char c2 = 'A';
System.out.println(c1 == c2); // 输出:true
2. 引用数据类型的比较
对于类、接口、数组等引用数据类型,==
和equals
的比较方式不同。
2.1 ==
比较引用
==
用于比较两个引用是否指向同一个对象实例,也就是比较对象在内存中的地址是否相同。
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // 输出:false,因为str1和str2指向不同对象
String str3 = "world";
String str4 = "world";
System.out.println(str3 == str4); // 输出:true,因为str3和str4指向字符串常量池中的同一个对象
2.2 equals
方法比较内容
equals
方法是Object
类的方法,在Object
类中,其默认实现等同于==
,即比较对象的引用。不过,许多类(如String
、Integer
、Date
等)会重写equals
方法,使其用于比较对象的内容。
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2)); // 输出:true,因为String类重写了equals方法,比较的是字符串内容
Integer num1 = new Integer(100);
Integer num2 = new Integer(100);
System.out.println(num1.equals(num2)); // 输出:true,因为Integer类重写了equals方法,比较的是数值
3. 自定义类的equals
方法
若你创建了自己的类,要根据内容而非引用进行比较,就需要重写equals
方法。重写时,通常还需重写hashCode
方法,以保证哈希表(如HashMap
、HashSet
)能正常工作。
public class Person {
private String name;
private int age;
// 构造方法、getter和setter略
// 重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
// 重写hashCode方法
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
// 使用示例
Person p1 = new Person("Alice", 20);
Person p2 = new Person("Alice", 20);
System.out.println(p1.equals(p2)); // 输出:true,根据内容比较
4. 常见误区与注意事项
- 字符串比较:
String s1 = "java"; // 指向字符串常量池 String s2 = new String("java"); // 指向堆中的新对象 System.out.println(s1 == s2); // 输出:false System.out.println(s1.equals(s2)); // 输出:true
- 包装类的缓存机制:
Integer a = 127; Integer b = 127; System.out.println(a == b); // 输出:true,因为-128到127之间的整数会被缓存 Integer c = 128; Integer d = 128; System.out.println(c == d); // 输出:false,超出缓存范围,创建了新对象
总结
比较方式 | 适用场景 | 比较内容 |
---|---|---|
== | 基本数据类型 引用数据类型 | 值 引用(内存地址) |
equals | 引用数据类型 | 内容(需类重写该方法) |
最佳实践
- 比较基本数据类型时,使用
==
。 - 比较引用数据类型时,优先使用
equals
方法,前提是该类重写了equals
方法。 - 自定义类时,若需要基于内容进行比较,就重写
equals
和hashCode
方法。