判断字符串是否相等必须分清目的:内容一致用equals(),引用相同用==;equals()逐字符比较内容且推荐字面量在前写法,==仅比较内存地址,实际开发中内容比较一律用equals()或Objects.equals()。

判断字符串是否相等,关键不是“怎么选”,而是“必须分清目的”:要内容一致,就用 equals();要确认是不是同一个对象,才看 ==。二者解决的是完全不同的问题,混用会出逻辑错误。
内容相等:一律用 equals() 方法
这是最常用、最安全的方式。equals() 逐字符比对两个字符串的实际内容,不管它们在内存中是不是同一块空间。
- 推荐写法:"abc".equals(str)(字面量在前),可避免 str 为 null 时抛 NullPointerException
- 忽略大小写比较用 equalsIgnoreCase(),比如 "Hello".equalsIgnoreCase("HELLO") 返回 true
- 如果不确定变量是否为空,更稳妥用 Objects.equals(str1, str2),它内部已处理 null 情况
内存地址相同:只用 == 判断引用一致性
== 比的是两个变量是否指向堆或常量池中的同一块内存地址,和内容无关。它返回 true 的情况非常有限:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 字符串字面量直接赋值:
String a = "test"; String b = "test";→a == b为 true(JVM 常量池复用) - 显式调用 intern():
new String("test").intern() == "test"为 true - 同一对象多次赋值:
String s = "x"; String t = s;→s == t为 true - new String("xxx") 创建的字符串,哪怕内容一样,也永远不会 == 其他字符串(包括字面量)
为什么不能靠 == 碰运气判断内容
因为 JVM 对字符串常量池的优化是确定的,但程序运行中大量字符串来自用户输入、JSON 解析、数据库读取等——这些几乎全是 new 出来的对象,地址必然不同。例如:
立即学习“Java免费学习笔记(深入)”;
-
Scanner sc = new Scanner(System.in); String input = sc.nextLine();→ input 一定不等于任何字面量 -
JSONObject.get("name").toString()返回的新字符串,和 "admin" == 比较永远 false - 看似相同的代码,一旦涉及 new、substring(某些版本)、StringBuilder.toString(),就可能脱离常量池
实际开发中的建议
- 所有业务逻辑里的“是否相同内容”判断,无一例外用 equals() 或 Objects.equals()
- 只有调试、单元测试验证对象复用,或极少数框架要求(如某些缓存 key 引用判重)才考虑 ==
- IDE 通常会对
str == "xxx"这类写法给出警告,别忽略——它提示你正在做危险操作 - 养成把字面量放 equals 左边的习惯:
"done".equals(status),防空指针又语义清晰

















