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的定义:

Android配合WebService访问远程数据库 中文WORD版
Android配合WebService访问远程数据库 中文WORD版

采用HttpClient向服务器端action请求数据,当然调用服务器端方法获取数据并不止这一种。WebService也可以为我们提供所需数据,那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合到一起。 实现Android与服务器端数据交互,我们在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,

下载
    /**
     * 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的源码以及调用栈来理解具体原因。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

804

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

723

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

727

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

395

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16861

2023.08.03

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.1万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 1.7万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 1.9万人学习

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

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