Java字符串equals比较效率取决于底层短路逻辑:先==判断引用,再类型检查、长度比较,最后逐字符遍历;需用JMH结合new String和末尾差异长字符串科学验证,而非简单背结论。

Java 字符串比较效率的面试题,核心不是背结论,而是理解底层逻辑并能设计合理验证方式。重点不在“谁快”,而在“为什么快”以及“在什么条件下快”。
看懂 equals 的执行路径
String.equals() 不是简单遍历字符。它有明确的短路优化顺序:
- 先用 == 判断是否为同一对象(地址相同),瞬间返回 true;
- 再判断参数是否为 String 类型(instanceof);
- 接着比长度,长度不同直接返回 false;
- 最后才逐字符比较(char 数组遍历),且从头开始、一旦发现不同立即退出。
这意味着:相同字符串、常量池复用场景下,equals 往往只需一次地址比较就结束;而两个长且前缀差异小的字符串,才真正走到耗时的循环阶段。
避开常见测试陷阱
很多“测性能”的代码其实测的是无效结果,因为 JVM 会干扰:
立即学习“Java免费学习笔记(深入)”;
- 编译期常量拼接(如 "a"+"b")会被优化成字面量,导致 == 也返回 true,无法反映真实 equals 开销;
- JIT 热点优化会让反复调用的代码被内联甚至消除,单次或少量循环测试毫无意义;
- 字符串复用(如 s1.equals(s1))永远走第一分支,不能代表一般情况。
正确做法:用 new String("xxx") 创建堆中独立对象,确保每次比较都进入完整流程;用足够长(如 1024 字符)、且仅末尾不同的字符串,迫使 equals 走完大部分循环。
用 JMH 做可信对比
手写 for 循环 + System.nanoTime() 容易受 GC、JIT 预热等影响,结果波动大。推荐用 JMH(Java Microbenchmark Harness):
- 自动处理预热、GC 控制、统计显著性;
- 可分别测试“相同字符串”“首字符不同”“末字符不同”三类典型 case;
- 能对比 equals、==、Objects.equals、甚至自定义 char[] 比较逻辑的开销差异。
例如:固定长度字符串,构造 s1 和 s2 仅最后一个字符不同,跑 JMH 测 equals 耗时,再换用 Arrays.equals(s1.toCharArray(), s2.toCharArray()) 对比——你会发现后者略慢,因为多了数组拷贝开销。
关注实际场景而非理论数字
面试官想听的不是“equals 比 == 慢 100ns”,而是你能否结合业务判断:
- Web 接口参数校验(如 status="success"):多数请求是预期值,equals 快得几乎无感;
- 密码比较:应避免 equals(存在时序攻击风险),改用 MessageDigest.isEqual;
- 大量日志字段去重:优先用 == 判定引用相等,再 fallback 到 equals,减少无效遍历。
效率问题最终要落到“数据特征+调用频次+安全要求”三者权衡上,而不是孤立谈方法本身。


















