结论:比较字符串一律用equals(),不用==;因为==比较内存地址,equals()比较字符内容,逻辑本质不同,字面量偶发相等不可依赖。

直接说结论:比较字符串,一律用 equals(),不用 ==。不是“看情况”,而是“必须如此”——因为 == 比的是内存地址,equals() 比的是字符内容,二者逻辑完全不同。
== 判断的是两个引用是否指向同一块内存
Java 中,== 对于所有引用类型(包括 String),只做一件事:检查左右两边的变量是否指向堆中同一个对象。哪怕内容一模一样,只要不是同一个对象,== 就返回 false。
- String s1 = new String("abc"); → 在堆中新建一个对象
- String s2 = new String("abc"); → 再建一个新对象,地址不同
- s1 == s2 → false(地址不同,哪怕内容相同)
equals() 判断的是字符串内容是否完全一致
String 类重写了 Object 的 equals() 方法,内部逐个比较字符数组的长度和每个 char 值。只要拼写、大小写、长度都一样,就返回 true。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- s1.equals(s2) → true(内容相同)
- 即使其中一个为 null,调用 s1.equals(s2) 会抛出 NullPointerException;但 s1 != null && s1.equals(s2) 或更安全地用 Objects.equals(s1, s2) 可避免
字面量字符串的 == 有时为 true 是特例,不是规则
像 String a = "hello"; String b = "hello"; 这种写法,JVM 会把字面量放入字符串常量池,并复用同一对象,所以 a == b 为 true。但这只是 JVM 的优化行为,不可依赖。
立即学习“Java免费学习笔记(深入)”;
- 一旦涉及 new,或运行时拼接(如 "he" + "llo" 在某些条件下不进池),== 就不可靠
- 开发中永远不该靠“碰巧 == 成立”来写逻辑,否则上线后极易出 bug
基本类型没有 equals(),包装类要注意 == 的陷阱
int、char 等基本类型只能用 ==,它们没有方法;而 Integer、Character 等包装类,== 在 -128~127 范围内可能因缓存复用返回 true,超出范围则 false——这完全是实现细节,业务代码绝不该依赖。
- Integer i1 = 100; Integer i2 = 100; → i1 == i2 可能为 true(缓存)
- Integer i3 = 200; Integer i4 = 200; → i3 == i4 极大概率是 false
- 统一用 i1.equals(i2) 才安全

















