结论:比较字符串一律用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。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 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 的优化行为,不可依赖。
- 一旦涉及 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) 才安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










