在Java中字符串比较怎么写_Javaequals与比较运算说明

用 equals() 比较字符串内容,别用 ==;== 比较引用地址,equals() 比较内容且对 null 安全;equalsIgnoreCase() 用于忽略大小写;Objects.equals() 适用于不确定类型或需统一处理 null 的场景。

equals() 比较字符串内容,别用 ==

Java 中字符串比较最常见错误:用 == 判断两个字符串是否“相等”。== 比较的是引用地址,不是内容。即使两个字符串字面值完全一样,如果来自不同对象(比如一个来自字面量池、一个用 new String() 创建),== 就会返回 false

正确做法是始终用 String.equals() 方法:

String a = "hello";
String b = new String("hello");
System.out.println(a == b);        // false
System.out.println(a.equals(b));   // true
  • equals() 会逐字符比对内容,区分大小写
  • 它会先检查参数是否为 null,所以传 null 不会抛 NullPointerException(但返回 false
  • 如果确定左操作数非空,也可以写成 "literal".equals(variable),避免变量为 null 时 NPE

equalsIgnoreCase() 用于忽略大小写的比较

当业务允许大小写不敏感时(比如用户名登录、配置项匹配),用 String.equalsIgnoreCase() 更安全直接:

String input = "HTTP";
System.out.println(input.equals("http"));           // false
System.out.println(input.equalsIgnoreCase("http")); // true
  • 内部逻辑和 equals() 类似,只是把每个字符转成小写再比
  • 同样对 null 参数返回 false,不会 NPE
  • 不要自己写 str.toLowerCase().equals(other.toLowerCase()) —— 效率低、还可能在某些 locale 下出错(比如土耳其语的 i 大小写规则特殊)

需要性能或常量校验时才考虑 ==

== 并非完全没用,但它只适用于明确知道两个字符串是“同一对象”或“都来自字符串常量池”的场景:

  • 字面量字符串自动入池:"abc" == "abc"true
  • 调用 String.intern() 后可强制入池,之后可用 == 安全比较(但代价是 GC 压力和 intern 表锁竞争,慎用)
  • 枚举字符串、配置常量、HTTP 方法名等固定值,在确认来源可控的前提下,有人用 == 做快速判断(如 method == GET),但前提是这些变量本身是 final 且指向 interned 字符串

绝大多数业务代码里,你不需要也不该依赖 == 来做语义相等判断。

注意 Objects.equals() 的通用兜底能力

当你不确定两个对象是否为 String(比如参数类型是 Object),或想统一处理 null 场景,可以用 java.util.Objects.equals()

String a = null;
String b = "test";
System.out.println(Objects.

equals(a, b)); // false,不抛异常 System.out.println(Objects.equals(a, null)); // true
  • 它内部就是先判空再调用 .equals(),语义清晰、无副作用
  • 适用于泛型方法、DTO 字段比较、单元测试断言等场景
  • 不要为了“看起来更通用”而在已知是 String 的地方强行套用——多一次方法调用,无实质收益

真正容易被忽略的点是:很多人记住了“用 equals”,却忘了检查调用方是否为 null;而另一些人过早优化,用 == 替代 equals(),结果在某次构建或 JVM 参数变更后突然出错——因为字符串是否入池、是否被 JIT 优化,有时并不稳定。