equals比较内容是否相等,==比较是否为同一对象;基本类型只能用==,引用类型==比较内存地址,equals默认同==但常用类已重写为逻辑比较,包装类在[-128,127]内==可能为true属JVM实现细节。

Java 中 equals 和 == 的核心区别在于:前者比较“内容是否相等”,后者比较“是否为同一个对象”(即内存地址是否相同)。这个区别看似简单,但实际使用中极易出错,关键要看数据类型和类是否重写了 equals 方法。
基本类型只能用 ==,不能用 equals
int、char、boolean 等 8 种基本数据类型没有方法,也不属于对象,因此不支持调用 equals()。试图对基本类型写 5.equals(5) 会直接编译失败。
它们之间只能用 == 比较值,比如:
int a = 10; int b = 10; System.out.println(a == b); // truedouble x = 3.14; double y = 3.14; System.out.println(x == y); // true
引用类型用 == 比较的是内存地址
String、Integer、ArrayList 等都是引用类型。用 == 判断时,只看两个变量是否指向堆中同一块内存。
立即学习“Java免费学习笔记(深入)”;
常见例子:
String s1 = new String("hello");String s2 = new String("hello");System.out.println(s1 == s2); // false —— 两个 new 出来的对象,地址不同String s3 = "world"; String s4 = "world";System.out.println(s3 == s4); // true —— 字符串常量池复用同一对象
equals 默认行为和重写后的语义
equals 是 Object 类的方法,原始实现就是 return (this == obj);,也就是和 == 效果一样。
但像 String、Integer、LocalDate 等常用类都重写了它,使其按“逻辑内容”比较:
"abc".equals("abc") // true —— 比字符序列new Integer(100).equals(100) // true —— 自动拆箱 + 值比较new ArrayList(Arrays.asList(1,2)).equals(Arrays.asList(1,2)) // true —— 比元素顺序和内容
自定义类如不重写 equals,默认仍比较地址;若需按字段判断相等(比如两个 User 对象 id 和 name 都相同即视为相等),必须手动重写 equals(通常也建议同时重写 hashCode)。
包装类的特殊表现:常量池影响 == 结果
Integer、Byte、Character 等部分包装类在 [-128, 127] 范围内会缓存对象(类似字符串常量池):
Integer a = 100; Integer b = 100; System.out.println(a == b); // trueInteger c = 200; Integer d = 200; System.out.println(c == d); // false(堆中各自 new)但 c.equals(d) 始终是 true —— 因为 Integer.equals() 比的是 int 值
这种现象不是规范保证的行为,而是 JVM 实现细节,所以永远别依赖 == 来判断包装类值是否相等。










