【Java避坑】为什么我的 String a == b 返回 false?一文搞懂 Java 中的 == 与 equals

你是不是也遇到过这种情况?明明两个字符串的内容一模一样,用if (str1 == str2)判断时,程序却无情地走进了else分支。

作为一个 Java 新手,这个问题曾困扰了我很久。今天我们来扒一扒这背后的原理,保证你看完后再也不会写错!

1. 案发现场

先看一段简单的代码:

String str1 = new String("hello"); String str2 = new String("hello"); if (str1 == str2) { System.out.println("它俩是一样的!"); } else { System.out.println("它俩不一样!"); // 结果竟然打印了这行? }

按照我们的直觉,str1str2都是 "hello",应该一样才对。为什么 Java 告诉我它们不一样?

2. 真相:你在比“地址”还是在比“长相”?

在 Java 的世界里,比较东西分两种情况。

A. == 操作符:比较的是“地址” (内存地址)

这就好比在问:“你们拿的是不是同一把家门钥匙?”

在上面的代码中,我们用了 new 关键字。new 的意思是在内存堆(Heap)里开辟一块新地盘。

  • str1住在一个地址(比如 0x111)。

  • str2 住在另一个地址(比如 0x222)。

    虽然它们房子里装修得一模一样,但它们是两栋不同的房子!所以 == 返回 false。

B. equals() 方法:比较的是“内容” (逻辑值)

这就好比在问:“你们的房子装修是不是一样的?”

如果我们换成 equals:

if (str1.equals(str2)) { System.out.println("它俩内容一样!"); // 打印这行 }

String类重写了equals方法,它会逐个字符去比较。只要字面一样,就返回true

3. 特殊情况:字符串常量池 (String Pool)

这里有个坑。如果你不用new,而是这样写:

String s1 = "hello"; String s2 = "hello"; System.out.println(s1 == s2); // 这里竟然是 true!

这是因为 Java 为了省内存,做了一个优化。当你直接写 "hello" 时,Java 会先去“字符串常量池”找有没有这个字。如果有,直接把地址给你;如果没有,才创建一个。

所以这里 s1 和 s2 确实拿的是同一把钥匙。

但千万别依赖这个!在实际开发中,数据往往是从数据库或者网络传来的,你无法保证它们在常量池里。

4. 总结与最佳实践

为了避免半夜调 Bug,请记住这条铁律:

在 Java 中,比较基本数据类型(int, boolean 等)用 ==;

比较对象(String, Integer, 自定义对象),永远使用 .equals()!


小技巧 (Pro Tip):

为了防止空指针异常(NullPointerException),建议把常量写在前面:

  • ❌ 坏习惯:if (userStatus.equals("ACTIVE"))(如果 userStatus 是 null,程序会崩)

  • ✅ 好习惯:if ("ACTIVE".equals(userStatus))(安全!)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1004834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细介绍:【分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【题解】Luogu P1310 [NOIP 2011 普及组] 表达式的值

题意 给定一个仅包含与或的中缀表达式,在每一个数值位填 0 或 1,求有多少种填法使得表达式的值为 0。 思路 统计方案数,首先考虑 DP。要想得知表达式的值,就要得知参与最后运算的两个值。这启示我们将中缀转后缀,…

教程 30 - 纹理系统

上一篇:从磁盘加载纹理 | 下一篇:材质系统 | 返回目录 📚 快速导航 📋 目录 引言学习目标系统架构概览哈希表容器实现纹理系统设计引用计数机制纹理获取与释放自动释放特性默认纹理管理系统集成着色器重命名使用示例常见问题练习…

Java面试三连击:原理拆解+实战避坑

很多刚学 Java 的小伙伴在面试时都会遇到一个尴尬的情况:题目明明看着很眼熟,答案也能背个大概,但面试官稍微追问一句“为什么”,就立刻哑口无言。今天我们精选了 3 道 Java 面试中出镜率最高的“老生常谈”,不讲枯燥的…

【题解】Luogu P11854 [CSP-J2022 山东] 宴会

题意 求一个点,使得数轴上所有点到一个点的距离加上其权值的最大值最小。 思路 三分 当选定点在所有点左侧时,距离最大值较大。 向右移动该点,最大值减小。 在所有点右侧时,最大值也较大。 由此可推测该最大值是一…

深入Ascend C(四):多算子融合与图级优化实战——构建高性能Attention自定义Kernel

引言 在前三篇文章中,我们系统学习了 Ascend C 的基础语法(第一篇)、卷积算子实现(第二篇)和 LayerNorm 优化(第三篇)。然而,在真实的大模型推理场景中,单个算子的极致优…

【题解】Luogu P5322 [BJOI2019] 排兵布阵

思路 考虑转化为背包问题。将每个玩家视为一组物品,每个城堡的出兵视为一个物品,因为如果要占领该城堡,就要出严格大于对手两倍的兵,所以每个物品的重量为 \(2\times a_i+1\),每个物品的价值为城堡编号。这样题目…

代码源挑战赛 Round 41

代码源挑战赛 Round 41 2025.12.12 A. [R41A]出题组3 link\(Solution:\) 用取模模拟即可。code #include <bits/stdc++.h> #define int long long #define ll long long #define ull unsigned long long #define…

详细介绍:NumPy / pandas 类型选型、内存占用与性能优化

详细介绍:NumPy / pandas 类型选型、内存占用与性能优化pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas…

告别选择困难!2025年远程控制软件场景化终极横评

推荐标题&#xff1a;告别选择困难&#xff01;2025年远程控制软件场景化终极横评 在混合办公成为常态的今天&#xff0c;远程控制软件已从“备用工具”升级为“生产力刚需”。面对市场上众多的选择&#xff0c;你是否也曾迷失在AI推荐、朋友安利和广告轰炸中&#xff1f;本文将…

一种可落地的任务令牌锁机制:设计原理、实战经验与容器化演进

以下是最近遇到的一个需求:同一类任务被部署在多个节点(虚拟机/容器)上,同一时刻只能由一个节点执行,但又必须保证高可用:当前节点宕机后,其它节点能够自动接管。如何简单、稳健、易调试地实现这样的需求? Red…

Flink学习笔记:状态类型和应用

Flink 被广泛应用的原因,除了我们前面提到的对时间以及窗口的应用之外,另一点就是它强大的容错机制,以及对 Exactly Once 的支持。Flink 被广泛应用的原因,除了我们前面提到的对时间以及窗口的应用之外,另一点就是…

[JSK]二叉苹果树

[JSK]二叉苹果树 大意 给定需要保留的树枝数量,求出最多能留住多少苹 果。苹果长在树枝上。 思路 这个题目和选课最大的不同在于其需要累加的贡献在边上,因此我们依旧设 \(f_{u, j}\),则有转移方程如下: \[f_{u, j…

Day 36 官方文档的阅读

浙大疏锦行 官方文档的检索方式&#xff1a;GitHub和官网 官方文档的阅读和使用&#xff1a;要求安装的包和文档为同一个版本 类的关注点&#xff1a; a.实例化所需要的参数 b.普通方法所需要的参数 c.普通方法的返回值 绘图的理解&#xff1a;对底层库的调用 import p…

【题解】Luogu P8137 [ICPC2020 WF] ’S No Problem

题目大意 给定一个无向树。有两个扫雪机可以任意选择出发终止点,可以走回头路。求两个扫雪机遍历整个树所需的最短路程。 解题思路 不妨先考虑只有一个扫雪机的情况。 我们知道,在无向树上从任意一个结点出发,将所有…

青少年编程学习:考级与竞赛如何平衡

青少年编程学习:考级与竞赛如何平衡 家长最关心的三个编程问题 在青少年编程学习过程中,家长常常面临几个核心困惑: 孩子学习编程,参加等级考试是否有必要? 在众多考试中,NCT和GESP应该如何选择? 如何平衡考级准备与竞赛训练,避免顾此失彼? 一、编程考级的价值:以考…

2025 Autel MaxiVCI V150 Wireless Dongle: CAN FD/DOIP for Autel 900 Series Scanners

The Diagnostic Tool Gap: Modern Vehicles Demand Modern Solutions For European and American automotive professionals and car owners, staying ahead of evolving vehicle technology is a daily challenge. To…

【UI Qt】入门笔记

目录 1、Qt 主要版本发展历程 2、各版本详细对比表 3、底层库对比 4、Qt基类 5、举例 6、QApplication与窗口关联 1、Qt 主要版本发展历程 版本 发布年份 主要特点 当前状态 Qt 1 1995 第一个公开版本&#xff0c;仅支持 Unix/X11 已淘汰 Qt 2 1999 引入信号槽…

WSL安装方法

WSL安装方法 【告别双系统,在Windows上无缝运行Linux,并使用GPU】传统双系统(独立安装 Windows + Linux) 优点:直接运行在硬件上,无性能损失。 缺点:每次切换系统都要重启电脑。虚拟机(VMware / VirtualBox) …

Ubuntu环境中LLaMA Factory 的部署与配置—构建大语言模型微调平台 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …