热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么Java字符串比较在Java15和Java11中表现不同?

请考虑以下类:classEq{publicstaticvoidmain(String[]args){System.out

请考虑以下类:

class Eq {
public static void main(String[] args) {
System.out.println("" == ".".substring(1));
}
}

该示例应该显示内存中可能存在空字符串的多个副本。我仍然有一个旧的 OpenJDK 11,程序false按预期输出。在 OpenJDK 15 下,程序输出true. 为类文件生成的字节码看起来相似(即使它们的寄存器值不同):

爪哇11:

public static void main(java.lang.String[]);
Code:
0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #13 // String
5: ldc #15 // String .
7: iconst_1
8: invokevirtual #17 // Method java/lang/String.substring:(I)Ljava/lang/String;
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #23 // Method java/io/PrintStream.println:(Z)V
22: return

爪哇 15:

public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String
5: ldc #4 // String .
7: iconst_1
8: invokevirtual #5 // Method java/lang/String.substring:(I)Ljava/lang/String;
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V
22: return

我试图通过阅读“.”来排除静态编译器优化。来自标准输入,但这不会改变结果。我试图禁用 JIT via-Djava.compiler=NONE并尝试通过调整字符串表大小-XX:StringTableSize=100000。我现在有以下问题:


  • 有人可以重现这个问题吗(即我做对了吗?如果有帮助,我可以提供类文件)

  • 我如何找出不同行为的确切原因?

  • (在您看来)不同行为的根源是什么?

我认为只是策略来解决如何找到不回答问题的行为的原因也可能很有趣。

回答


这在JDK 15 发行说明 中提到。

根据 JDK-8240094 的要求对其进行了更改:

JDK-8240094:优化空子串处理

String.substring""在某些情况下返回,但可以改进以在子字符串长度为零的所有情况下都这样做。

有关的:

JDK-8240225:优化空子串处理

优化String.substring和相关操作,如stripLeading,stripTrailing避免重复创建新的空字符串。

子任务:

JDK-8251556:发行说明:优化的空子字符串处理

的实施String.substring和相关方法stripLeadingstripTrailing在此版本中已更改为避免冗余创建一个新的空字符串。这可能会影响依赖于未指定行为和空子字符串标识的代码。




  • @fluffy `""` is the default empty string constant, no need to create a constant field for it, since string literals are always interned for you.


  • @fluffy The string constant pool is synthesized by the JVM at runtime and merges all constant strings.


  • @fluffy it doesn’t matter whether you use `""` or `SomeClass.CONSTANT`. The important point is that the `substring` method needs to perform an explicit test whether the result string has length zero and use one of those constants instead of calling `new String(…)` in that case. Without that test, declaring a constant for empty strings doesn’t help.


  • @fluffy having public constructors in the string class is a historical design mistake on its own (including `String()`, encouraging developers to create redundant strings even when known to be empty). However, for the string class itself, that makes little difference as even `private` constructors are accessible. Consistently using factory methods that may perform this check would help, but there is a different point of view. *Is this optimization really an improvement?* We now have an additional conditional in every `substring` operation, serving the rare corner case of an empty result…


  • Just curious: .NET has `String.Empty` since the earliest version, Apache Commons suggest a similar final reference `StringUtils.EMPTY`. Those JDK items and issues would probably never exist if an empty string constant would exist from the very beginning. Was there any idea of introducing the "default" empty string constant to Java?


  • @fluffy I had such scenarios in my application, where I wished I could constrain the use of `private` members even further, ala “this member is only for method abc and xyz”. However, in case of OpenJDK’s String implementation they were not even trying to use/enforce factory methods, internally, the constructors are used all over the place.





推荐阅读
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 检查在所有可能的“?”替换中,给定的二进制字符串中是否出现子字符串“10”带 1 或 0 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • AIX编程挑战赛:AIX正方形问题的算法解析与Java代码实现
    在昨晚的阅读中,我注意到了CSDN博主西部阿呆-小草屋发表的一篇文章《AIX程序设计大赛——AIX正方形问题》。该文详细阐述了AIX正方形问题的背景,并提供了一种基于Java语言的解决方案。本文将深入解析这一算法的核心思想,并展示具体的Java代码实现,旨在为参赛者和编程爱好者提供有价值的参考。 ... [详细]
  • JVM钩子函数的应用场景详解
    本文详细介绍了JVM钩子函数的多种应用场景,包括正常关闭、异常关闭和强制关闭。通过具体示例和代码演示,帮助读者更好地理解和应用这一机制。适合对Java编程和JVM有一定基础的开发者阅读。 ... [详细]
  • Hadoop的文件操作位于包org.apache.hadoop.fs里面,能够进行新建、删除、修改等操作。比较重要的几个类:(1)Configurati ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流
    字节流抽象类InputStream和OutputStream是字节流的顶级父类所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStreamInput ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 2022年7月20日:关键数据与市场动态分析
    2022年7月20日,本文对当日的关键数据和市场动态进行了深入分析。主要内容包括:1. 关键数据的解读与趋势分析;2. 市场动态的变化及其对投资策略的影响;3. 相关经济指标的评估。通过这些分析,帮助读者更好地理解当前市场环境,为决策提供参考。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
author-avatar
手机用户2502940275
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有