偷看了隔壁老王的文章,发现String拼接另有天地

简介: 偷看了隔壁老王的文章,发现String拼接另有天地

最近开始上班,路上时间变长为1小时,目前还没找到路上可以干点啥。于是就刷刷公众号文章,今天早上一不小心“偷看”了老王(公众号:Java中文社区)的一篇关于String性能提升方法分析的文章。引发了一场底层代码实现的探索。

老王的文章中关于字符串的处理和效率提升都没错,但在总结中提到“不要直接+=字符串”的建议却引起我的怀疑。在路上就进行了评论:

“+=操作记得在最新版本是分场景的,比如正常来说没有使用for循环这种情况,jdk默认会转换StringBuilder来进行操作,而for循环内它会在for循环内不停的创建StringBuilder,所以才需要在外面声明。”

老王的回复是:我看很多资料也是这样说,但jdk8和jdk11我反编译都没发现这种情况。

原本结论和建议是没错的,但技术人有时候就爱较个真。于是到公司的第一件事就是写了两个程序来验证。

第一个程序:








public class TestString {  public static void main(String[] args) {    String a = "a";    String b = a + "b";    System.out.println(b);  }}

先尝试了反编译,发现反编译之后与源代码一样,也就是说通过反编译看不出来差别。那就查看字节码。

执行:

javap -c TestString.class

显示结果:

image.png通过字节码看到,的确是被优化,创建了StringBuilder,然后再进行字符串拼接。随后又验证一下for循环的情况,是不是每次在for循环内部都会新创建一个StringBuilder。










public class TestString {  public static void main(String[] args) {    String a = "a";    for(int i=0; i< 3; i++){      a += ("a" + i);    }    System.out.println(a);  }}

查看对应字节码如下: image.png这里在for循环中虽然没有重复创建StringBuilder,但还是默认将String字符串转换为StringBuilder进行处理了。以上验证采用的是Oracle官方jdk8进行测试的。

于是,开始给老王发信息,进行“挑战”。不一会儿老王也发来回复消息,说:为什么我都不是这样呢?并附带了截图。image.png一看他的截图,还真是不一样。于是开始一起比对环境,后来才发现他使用的是如下版本:





✗ java -version'openjdk version "14" 2020-03-17OpenJDK Runtime Environment (build 14+36-1461)OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)

于是,一场争辩结束,随之大家共同发现一件事。网络上流传的JDK8默认帮忙优化String字符串拼接为StringBuilder在openjdk的分支上并不成立,而在Oracle提供的JDK版本中才成立,而且要JDK8及以上版本。

其实经过几轮的讨论和各种尝试,发现网络上的一句话成立可能是有很多先决条件的,真是“理儿越变越明”。同时,技术也只有在这种碰撞中才能快速提升。

今天文章为大家分享了一个技术点,学到了便是赚了。但如果你能通过整个事件的过程总结一套学习如何从分歧中获得新知,如果从疑问中实践出新知,那么你真的是赚大发了。

目录
相关文章
|
7月前
|
C++ 容器
C++字符串string容器(构造、赋值、拼接、查找、替换、比较、存取、插入、删除、子串)
C++字符串string容器(构造、赋值、拼接、查找、替换、比较、存取、插入、删除、子串)
|
7月前
|
安全 Java API
JavaSE——常用API进阶一(3/3)-StringBuilder(构造器、拼接内容、反转操作、其他操作),StringBuffer,StringJoiner
JavaSE——常用API进阶一(3/3)-StringBuilder(构造器、拼接内容、反转操作、其他操作),StringBuffer,StringJoiner
49 1
|
7月前
|
Dart
Dart中的String类型定义与拼接
Dart中的String类型定义与拼接
|
8月前
|
存储 C++ 索引
C++中的string容器及字符串拼接操作讲解
C++中的string容器及字符串拼接操作讲解
257 3
|
安全 Java API
Java的第十篇文章——常用类下(String、大数类、日期类和包装类)
Java的第十篇文章——常用类下(String、大数类、日期类和包装类)
|
安全 Java API
Java的第八篇文章——Object类、String类和StringBuilder类
Java的第八篇文章——Object类、String类和StringBuilder类
|
安全 Java 编译器
详细讲解String拼接原理,介绍StringBuilder和StringBuffer
详细讲解String拼接原理,介绍StringBuilder和StringBuffer
详细讲解String拼接原理,介绍StringBuilder和StringBuffer
|
安全 Java 编译器
Java中String、StringBuffer和StringBuilder字符串拼接原理
String:适用于少量的字符串操作的情况; StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况; StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况;
201 0
Java中String、StringBuffer和StringBuilder字符串拼接原理
|
Java 数据安全/隐私保护 索引
Java中字符串遍历、统计次数、拼接、反转案例及String常用方法
字符串遍历、统计次数、拼接、反转案例及String常用方法的简单示例
545 0
|
Java 测试技术 API
Java 中拼接 String 的 N 种方式
Java 中拼接 String 的 N 种方式
501 0
Java 中拼接 String 的 N 种方式