1. ==
运算符
-
作用:比较两个对象的 内存地址(引用类型)或 值(基本数据类型)。
-
适用场景:
-
基本数据类型(
int
,char
,boolean
等):直接比较值是否相等。 -
引用类型(对象):比较两个变量是否指向同一个内存地址(即是否为同一个对象)。
-
示例:
int a = 10;
int b = 10;
System.out.println(a == b); // true(基本数据类型比较值)
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false(引用类型比较内存地址)
2. equals
方法
-
作用:默认情况下(
Object
类的实现),equals
和==
一样比较内存地址。但大多数类(如String
、Integer
)会 重写equals
方法,改为比较对象的 内容 是否相等。 -
适用场景:
-
引用类型:比较对象的逻辑内容是否相等(需依赖具体类的
equals
实现)。
-
示例:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1.equals(s2)); // true(String 重写了 equals,比较内容)
// 自定义类默认比较内存地址
class Person {
String name;
Person(String name) { this.name = name; }
}
Person p1 = new Person("Tom");
Person p2 = new Person("Tom");
System.out.println(p1.equals(p2)); // false(未重写 equals)
3. 关键区别总结
比较项 | == | equals |
---|---|---|
比较对象 | 内存地址(引用类型)或值(基本类型) | 对象的内容(需重写 equals 方法) |
基本数据类型 | 直接比较值 | 不适用(基本类型没有方法) |
引用类型 | 比较是否为同一对象 | 比较内容是否逻辑相等 |
自定义类 | 默认比较内存地址 | 需手动重写 equals 方法 |
4. 注意事项
-
字符串常量池的特殊性:
String s1 = "hello"; // 字符串常量池中的对象 String s2 = "hello"; // 复用常量池中的对象 System.out.println(s1 == s2); // true(指向同一对象) String s3 = new String("hello"); // 堆中新对象 System.out.println(s1 == s3); // false
-
重写
equals
必须同时重写hashCode
:-
如果两个对象
equals
返回true
,它们的hashCode
必须相同(例如用于HashMap
的键)。
-
-
包装类的比较陷阱:
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(超出缓存范围) System.out.println(c.equals(d)); // true(比较值)
5. 如何正确使用?
-
基本数据类型:直接用
==
。 -
引用类型:
-
如果要比较内存地址(是否为同一对象),用
==
。 -
如果要比较内容是否相等,用
equals
(确保该类已正确重写equals
方法)。
-
-
自定义类:必须重写
equals
和hashCode
方法以支持逻辑相等性比较。
总结
-
==
是运算符,比较值或内存地址。 -
equals
是方法,默认比较内存地址,但可被重写为比较内容。 -
字符串和包装类等常用类已重写
equals
,但自定义类需手动实现。