Java中String的equals()方法先用==判引用、再检查String类型、接着比长度、最后逐字符比较,根本原因是兼顾正确性、性能和安全性:地址相同可立即返回true;instanceof隐式防null;长度不等提前终止;字符比对留到最后精准验证。

Java中String的equals()方法之所以先判断引用、再比长度、最后逐字符比较,根本原因是**兼顾正确性、性能和安全性**——不是随意安排的顺序,而是经过充分权衡的工程设计。
为什么第一步必须用==判断引用
这是最廉价的快速路径。如果两个变量指向同一个对象(比如字符串字面量复用或同一new实例),内容必然完全一致,无需后续任何操作。JVM能瞬间完成地址比对,避免数组长度读取、类型检查、循环开销。实际开发中,这种“自比”或常量池内复用的情况并不少见,跳过冗余步骤直接返回true,显著提升高频调用场景的效率。
为什么第二步检查是否为String类型
因为equals(Object)接收任意对象,而String只接受String类型的参数做内容比较。如果不是String(比如传入Integer、null或自定义类),逻辑上就不可能内容相等,必须立即返回false。这一步也隐含了空值防护:如果参数是null,instanceof String结果为false,自然走到末尾的return false,**无需单独写if (anObject == null)判空**——源码里没显式判null,正是靠这一机制实现的简洁健壮。
为什么长度不等就立刻终止
长度是内容相等的必要前提。两个字符串字符数不同,哪怕前N-1个字符全一样,也不相等。“hello”.equals("hell")在长度检查阶段就返回false,省去了5次字符读取+比较+索引递增的操作。这对长字符串尤其关键——避免无谓遍历整个char数组。
立即学习“Java免费学习笔记(深入)”;
为什么最后才逐字符比较
这是真正决定相等性的核心步骤,但代价最高。源码中采用while循环按索引顺序比对,从头到尾逐个检查char值(Unicode码点)。一旦发现某位置字符不同,立刻返回false;只有全部通过才返回true。这个阶段无法进一步“跳过”,因为内容一致性必须完整验证。
整套流程就是典型的“由快到慢、由粗到精”的分层过滤:地址相同→类型合法→长度匹配→字符逐一对齐。每一步都筛掉大量不满足条件的情况,把最重的计算留到最后、且仅在必要时执行。这不是教科书式的逻辑推导,而是JDK工程师在真实性能压测和常见用例分析后沉淀下来的实践智慧。


















