社交媒体

== 和 equals() 的区别

== 和 equals() 的区别

钩子:看着一样,== 却说 false

String s1 = "橙码酱";
String s2 = new String("橙码酱");

System.out.println(s1 == s2);        // false !
System.out.println(s1.equals(s2));   // true

内容明明一样,== 却说它们不相等。为什么?

核心:== 比地址,equals 比内容

回想第 14 篇:变量存的是对象的地址(遥控器),不是对象本身。

  • == 比较:两个遥控器是不是控制同一台机器(地址是否相同);
  • equals 比较:两台机器里的内容是不是一样(默认比地址,但 String 等类重写过它,改成比内容)。

上面 s1 指向常量池里的"橙码酱",s2 指向堆里 new 出来的另一个"橙码酱"——两个不同的对象,地址不同,所以 == 是 false;但内容一样,equals 是 true。

22-==与equals对比图.png

三个必懂的坑

坑 1:比较字符串内容,永远用 equals

if (name == "admin") { ... }          // 错误示范
if (name.equals("admin")) { ... }     // 正确

坑 2:equals 的防空指针写法

// 如果 name 可能是 null:
if ("admin".equals(name)) { ... }     // 把常量放前面,永远不会 NPE

name.equals("admin") 在 name 为 null 时直接抛 NullPointerException;反过来写就安全。这是新手线上事故的常客。

坑 3:什么时候 == 反而是对的?

基本类型(int、long、char…)没有对象、没有地址,== 比的就是值本身——这时候用 == 完全正确:

int a = 10;
if (a == 10) { ... }   // ✔ 基本类型用 ==

记住分界线:基本类型比值用 ==,对象比内容用 equals。

一个加分知识:常量池

String a = "橙码酱";
String b = "橙码酱";
System.out.println(a == b);   // true !

字面量字符串存在常量池里,相同的字面量共用一个对象(第 21 篇说过,这只有在 String 不可变的前提下才成立)。所以 a 和 b 地址相同,== 是 true——但这只是"恰好相等",判断内容依然永远写 equals,这是习惯问题。


本文示例代码均已本地实测通过,可直接运行。
对应文件:EqualsDemo.java


橙码酱,分享更有用的技术知识,助你成为更优秀的开发者。