Java 怎么判断字符串是否相等?两种比较写法一次讲清

编程狮(w3cschool.cn) 2026-08-14 15:14:43 浏览数 (26)
反馈

你写了两个内容看起来一模一样的字符串,用 == 一比,结果居然是 false,程序当场翻车。这几乎是每个 Java 新手都会踩的坑。原因其实很简单:在 Java 里,== 比较的是“这两个变量是不是指向同一个对象(也就是同一块内存地址)”,而字符串的内容到底相不相同,得用 equals 方法去比。今天这篇文章,编程狮就把 Java 怎么判断字符串相等这件事讲透,顺带告诉你怎么避开空指针这个更隐蔽的坑。

一、为什么 == 比不出来:引用和内容的区别

要弄懂字符串相等,得先分清“引用”和“内容”。当你写 String a = "hello"; 时,a 里存的是一个引用,它指向内存里那块写着 hello 的对象。== 只关心两个引用指的不是不是同一块内存,不关心里面的字是不是一样。

💡 小提示:由于 Java 有字符串常量池,写死在代码里的字面量有时会被复用同一块内存,导致 == 偶尔“碰巧”返回 true。但这是优化带来的偶然,绝不能当成规律来依赖。

举个具体场景:你从接口拿到一个用户输入的字符串 input,再用 equals("admin") 去比对,这是对的;但如果你写 input == "admin",几乎一定是 false,因为 input 是运行时新建的对象,和代码里的字面量 "admin" 根本不是同一块内存。这正是字符串比较里最经典的坑。

理解字符串比较的关键,是接受“Java 的 String 是不可变对象”这件事。每次拼接、截取都会产生新对象,== 永远在比“是不是同一个对象”,而业务想要的几乎总是“内容一不一样”。把这两件事分清楚,equals 和 == 就不会再让你困惑。

所以 Java 里的字符串比较,记住一条铁律:比内容用 equals,绝不靠 ==。判断 Java 字符串相等,不能靠 ==,而要靠专门比较内容的办法。想补全 Java 基础,Java 教程 里对字符串和对象模型的讲解很系统,建议搭配看。

二、方法一:用 equals 比较内容(最常用)

最标准、最常用的是调用字符串的 equals 方法:

String a = "hello";
String b = "hello";
boolean same = a.equals(b); // true

equals 会比较两个字符串里的每一个字符,全部一致才返回 true。这正是我们判断字符串相等真正想要的语义:看内容,不看内存地址。equals 之所以可靠,是因为 String 类重写了它——不再比地址,而是逐个字符比较,连 Unicode 字符也能正确识别。所以不管字符串怎么来的,只要字符序列一致,equals 就返回 true,这也是为什么它是字符串比较的事实标准。

我们可以故意制造一个 == 翻车的例子:

String a = new String("hello");
String b = new String("hello");
System.out.println(a == b);      // false,两个不同对象
System.out.println(a.equals(b)); // true,内容相同

new String() 强制创建两个独立对象后,== 立刻暴露出“比地址”的本质,而 equals 依然稳稳比内容。绝大多数业务代码里,判断两个字符串相不相等,用的都是 equals,它语义清晰、行为可预期。

⚠️ 注意:equals 区分大小写。"Hello" 和 "hello" 用 equals 比是不一样的。如果你的场景需要忽略大小写,请看下面的方法二。

这个写法几乎覆盖了九成以上的字符串比较场景;剩下要处理大小写的情况,我们接着看方法二。

三、方法二:用 equalsIgnoreCase 忽略大小写

当你只关心“字母对不对、不关心大小写”时,比如比较邮箱、验证码,可以用 equalsIgnoreCase:

String code = "AbC";
boolean ok = code.equalsIgnoreCase("abc"); // true

这个方法会把两边统一成同一种大小写再比较,适合用户输入可能大小写混用的情况。但它同样只比内容、不比引用,和 == 是两码事。一个真实场景:用户填邮箱登录,可能随手大写了一点,用 equals 比会判不等、登录失败,换成 equalsIgnoreCase 就能宽容通过。但注意,密码绝不能忽略大小写——那种场景必须严格 equals,否则等于降低安全门槛。关于字符串的其他常见操作,Java 子串查找方法 里还讲了怎么在字符串里找子串,可以一起看。

四、最稳的写法:先判空再比较,躲开空指针

equals 有个大坑:如果左边的字符串是 null,调用 a.equals(b) 会直接抛出 NullPointerException。最稳的写法是把“确定非空的常量”放左边,或者先用工具判空:

// 常量在左,null 也不会崩
boolean same = "hello".equals(userInput);

这样即使 userInput 是 null,也只会返回 false,不会让程序崩溃。判断 Java 字符串相等时,永远先想清楚“哪边可能为 null”,把非空常量放左边只是最朴素的解法。更严谨的写法是直接用 Objects.equals(a, b),它内部已经帮你处理了 null 情况,两边谁为 null 都不会崩,在不确定时用它最省心。另外还有个进阶技巧:String.intern() 能把字符串手动塞进常量池,让 == 也能比内容,但这会拖慢性能、还可能撑爆池子,实战中几乎没人这么干。记住结论就好:字符串比较永远用 equals 系列,别和 == 较劲。顺带一提,比较字符串时如果一边是常量、一边来自网络或数据库,永远优先用 equals 系列并配合判空,这是写过几年 Java 的人都认同的共识。把字符串转成数字这类场景,Java 字符串转数字 讲了配套的处理方式,值得参考。

总结

判断 Java 字符串相等,记住一句话:比内容用 equals,别用 ==。== 比的是内存地址,equals 比的是字符内容;要忽略大小写用 equalsIgnoreCase;要避免空指针,就把确定的非空值放左边再调用。

把“== 用于基本类型、equals 用于字符串内容”这条记牢,你就能彻底绕开这个经典新手坑。以后再看到字符串比较,先问自己一句“比的是地址还是内容”,答案自然就清楚了,代码也就不会再因为这个翻车。

常见问题

Q:为什么有时候 == 比较两个字符串又返回 true 了?
A:因为 Java 的字符串常量池会复用字面量,写死的 "hello" 可能指向同一块内存,让 == 偶尔碰巧为 true。这是偶然优化,不可依赖,正式代码一律用 equals。

Q:equals 和 equalsIgnoreCase 性能差别大吗?
A:几乎没有可感知的差别。忽略大小写只是多一步归一化,日常业务里优先选语义正确的那个,不必为这点开销纠结。

Q:比较字符串要不要先转成小写再 equals?
A:可以,但用 equalsIgnoreCase 更直观也更安全。自己手动转小写要注意字符集问题,能交给现成方法就别手写。

延伸学习

想把 Java 基础打牢,可以按这个顺序来:

  1. 方法记不住时,Java 速查手册 能随时翻查;
  2. 想跟着视频边学边练,Java入门课程 是循序渐进的形式,适合巩固上手。

0 人点赞