0

0

Java String类equals方法的工作机制是什么?

碧海醫心

碧海醫心

发布时间:2025-03-20 10:14:01

|

656人浏览过

|

来源于php中文网

原创

探究java string类equals方法的工作机制

在学习java string类的equals方法时,我们经常会遇到一些困惑,尤其是当深入到源码时,会发现一些不易理解的现象。今天我们将深入探讨jdk18环境下string类的equals方法的内部逻辑,揭示其中的奥秘。

问题描述

在使用断点调试时,观察到了以下现象:

问题1:

return (anobject instanceof string astring)
       && (!compact_strings || this.coder == astring.coder)
       && stringlatin1.equals(value, astring.value);

这个逻辑似乎在调试过程中循环运行。而且,有时即使字符相同,如"a".equals("a")时,value与astring.value的数组长度也会不同。

问题2:

立即学习Java免费学习笔记(深入)”;

  • 对于"a".equals(new string("a"));,调试时发现传递的参数如图所示:
    [参数图像]
  • 对于"a".equals("a");,调试时发现传递的参数如图所示:
    [参数图像]

这两个例子中,参数在传递到equals方法后,似乎并不总是如预期的"a"。

解答

让我们从string类的源码开始,逐步理解这些现象。首先,关于compact_strings的定义和说明:

    /**
     * if string compaction is disabled, the bytes in {@code value} are
     * always encoded in utf16.
     *
     * for methods with several possible implementation paths, when string
     * compaction is disabled, only one code path is taken.
     *
     * the instance field value is generally opaque to optimizing jit
     * compilers. therefore, in performance-sensitive place, an explicit
     * check of the static boolean {@code compact_strings} is done first
     * before checking the {@code coder} field since the static boolean
     * {@code compact_strings} would be constant folded away by an
     * optimizing jit compiler. the idioms for these cases are as follows.
     *
     * for code such as:
     *
     *    if (coder == latin1) { ... }
     *
     * can be written more optimally as
     *
     *    if (coder() == latin1) { ... }
     *
     * or:
     *
     *    if (compact_strings && coder == latin1) { ... }
     *
     * an optimizing jit compiler can fold the above conditional as:
     *
     *    compact_strings == true  => if (coder == latin1) { ... }
     *    compact_strings == false => if (false)           { ... }
     *
     * @implnote
     * the actual value for this field is injected by jvm. the static
     * initialization block is used to set the value here to communicate
     * that this static final field is not statically foldable, and to
     * avoid any possible circular dependency during vm initialization.
     */
    static final boolean compact_strings;

    static {
        compact_strings = true;
    }

从这段说明可以看出,如果compact_strings为false,value将始终使用utf16编码。这个设置和coder字段密切相关。

接下来,我们看看coder的定义:

闪念贝壳
闪念贝壳

闪念贝壳是一款AI 驱动的智能语音笔记,随时随地用语音记录你的每一个想法。

下载
    /**
     * the identifier of the encoding used to encode the bytes in
     * {@code value}. the supported values in this implementation are
     *
     * latin1
     * utf16
     *
     * @implnote this field is trusted by the vm, and is a subject to
     * constant folding if string instance is constant. overwriting this
     * field after construction will cause problems.
     */
    private final byte coder;

coder有两个可能的值,分别表示latin1和utf16。我们可以找到与coder同名的方法:

    byte coder() {
        return compact_strings ? coder : utf16;
    }

因此,条件(!compact_strings || this.coder == astring.coder)的意义就很明确了:

如果compact_strings == false,就使用utf16编码,继续检查下一个条件。如果条件不成立,就检查coder是否相同,如果不相同,直接返回false。我们可以用手写代码来理解这个逻辑:

boolean flag = false;
if (!compact_strings) {
    flag = true; // 根据 compact_strings 的说明,这种情况下使用 utf16,忽略 coder 值
} else if (this.coder == astring.coder) {
    flag = true; // 说明 coder 一致
}

然后,stringlatin1.equals(value, astring.value)条件中,内部数据value使用latin1编码规则进行比较。value的定义如下:

    /**
     * The value is used for character storage.
     *
     * @implNote This field is trusted by the VM, and is a subject to
     * constant folding if String instance is constant. Overwriting this
     * field after construction will cause problems.
     *
     * Additionally, it is marked with {@link Stable} to trust the contents
     * of the array. No other facility in JDK provides this functionality (yet).
     * {@link Stable} is safe here, because value is never null.
     */
    @Stable
    private final byte[] value;

因此,equals方法的完整逻辑如下:

  1. 首先判断是否是字符串,如果不是,直接返回false。
  2. 检查是否具有相同的coder(compact_strings的值间接影响coder的一致性比较),如果不同,直接返回false。
  3. 在coder相同的情况下,比较内部数据是否一致,决定最终的比较结果。

补充说明:

关于utf16的比较方式,源码中仅使用了stringlatin1.equals,但如果确定编码规则相同,底层按字节比较的方法仍然适用。如果想要更详细了解utf16的比较,可以进一步研究stringlatin1的实现。

对于断点调试时观察到的“循环运行”现象,实际上并没有循环语句。调试过程中,可能会因为编码比较而导致这种现象。如果发现调试时传递的参数是“gbk”,这可能是因为在比较过程中涉及了编码转换。这需要进一步查看stringlatin1的源码以及调用栈来理解具体原因。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

651

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1205

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.07.29

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号