在 Java 中,==
和 equals()
是两种不同的比较机制,它们的区别主要体现在 比较对象类型 和 比较逻辑 上:
一、==
运算符
-
基本数据类型(如
int
,double
,boolean
等)
==
直接比较 值是否相等。
int a = 5;
int b = 5;
System.out.println(a == b); // true(值相等)
- 引用类型(如对象、数组、String 等)
==
比较 内存地址是否相同(即是否指向同一个对象)。
String s1 = new String("Java");
String s2 = new String("Java");
System.out.println(s1 == s2); // false(不同对象,内存地址不同)
二、equals()
方法
-
默认行为(未重写时):
继承自Object
类,底层使用==
比较内存地址。
Object obj1 = new Object();
Object obj2 = new Object();
System.out.println(obj1.equals(obj2)); // false(比较地址,等同 ==)
-
重写后的行为:
多数 Java 类(如String
、Integer
、自定义类)会重写equals()
,使其比较 对象的内容是否等价。
String s1 = new String("Java");
String s2 = new String("Java");
System.out.println(s1.equals(s2)); // true(内容相同)
三、关键区别总结
== | equals() | |
---|---|---|
适用类型 | 基本类型 + 引用类型 | 仅引用类型 |
比较依据 | 基本类型:值;引用类型:内存地址 | 默认比较地址,重写后比较内容 |
示例场景 | int 、直接赋值字符串常量池比较 | String 、自定义对象内容比较 |
四、经典案例:String 的两种创建方式
1、字符串常量池:
String a = "Java"; // 常量池中创建
String b = "Java"; // 直接引用常量池中的对象
System.out.println(a == b); // true(内存地址相同)
2、显式 new
对象:
String c = new String("Java"); // 堆中新建对象
String d = new String("Java"); // 堆中另一个对象
System.out.println(c == d); // false(地址不同)
System.out.println(c.equals(d));// true(内容相同)
五、注意事项
1、自定义类必须重写 equals()
才能实现内容比较:
class Person {
String name;
public boolean equals(Object obj) {
if (obj instanceof Person) {
return this.name.equals(((Person) obj).name);
}
return false;
}
}
2、重写 equals()
必须同时重写 hashCode()
,确保哈希一致性(例如在 HashMap
中正确使用)。
3、避免空指针:推荐使用 Objects.equals(a, b)
(Java 7+)安全比较:
String s1 = null;
String s2 = "Java";
System.out.println(Objects.equals(s1, s2)); // false(不会抛异常)
六、总结
==
:基本类型比值,引用类型比地址。-
equals()
:默认比地址,重写后比内容。 - 实践建议:引用类型比较内容时,优先用
equals()
,但对可能为null
的对象使用工具类Objects.equals()
。