老板扣了我1000,因为我没记住阿里巴巴开发手册的这条规则。
发布日期:2021-06-29 22:13:31 浏览次数:3 分类:技术文章

本文共 4109 字,大约阅读时间需要 13 分钟。

640?wx_fmt=jpeg

来源:Java面试那些事儿

本文故事构思来源于脉脉上的一篇帖子“一行代码引发的血案640?wx_fmt=png”。

640?wx_fmt=jpeg

其实关于字符串的文章,我之前也写过一篇《诡异的字符串问题》,字符串对于我们开发者而言,可以用最近很流行的一句话“用起来好嗨哟,仿佛人生达到了巅峰”。

确实大家都用的很嗨,很便利,但 JDK 的工程师在背后付出了努力又有几个人真的在意呢?

咱们今天就通过一个例子来详细的说明。

public class StringTest {
public static void main(String[] args) {
// 无变量的字符串拼接      String s = "aa"+"bb"+"dd";        System.out.println(s);        // 有变量的字符串拼接        String g = "11"+s+5;        System.out.println(g);        // 循环中使用字符串拼接        String a = "0";        for (int i = 1; i < 10; i++) {
a = a + i;        } System.out.println(a);        // 循环外定义StringBuilder        StringBuilder b = new StringBuilder();        for (int i = 1; i < 10; i++) {
b.append(i);        } System.out.println(b);    } }

有同学可能会说,这么一段代码,怎么来区分呢?既然我在对话中说了 Java 从 JDK5 开始,便在编译期间进行了优化,那么编译期间 javac 命令主要干了什么事情呢?一句话归根结底,那么肯定就是把 .java 源码编译成 .class 文件,也就是我们常说的中间语言——字节码。然后 JVM 引擎再对 .class 文件进行验证,解析,翻译成本地可执行的机器指令,这只是一个最简单的模型,其实现在的 JVM 引擎后期还会做很多优化,比如代码热点分析,JIT编译,逃逸分析等。

说到这里,我记得之前群里有同学说,字节码长得太丑了,看了第一眼就不想看第二眼,哈哈,丑是丑点,但是很有内涵,能量强大,实现了跨平台性。

关于怎么查看字节码,我之前分享过两个工具,一个 JDK 自带的 javap,另一个IDEA的插件 jclasslib Bytecode viewer。今天给你再分享一个,我之前破解 apk 常用的工具 jad,它会让你看字节码文件轻松很多。

先说一下,我分别用 Jdk 1.6 - 1.8 自带的 javap 工具进行了反编译,发现生成的 JVM 指令是一样的,所以在此处不会列出每一个版本生成的指令文件。为了便于大家阅读指令文件,这里用jad工具生成,代码如下。

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. // Jad home page: http://www.kpdus.com/jad.html // Decompiler options: packimports(3) annotate // Source File Name:   StringTest.java import java.io.PrintStream; public class StringTest {
public StringTest() {
// 0 0:aload_0 // 1 1:invokespecial #1
// 2 4:return } public static void main(String args[]) {
String s = "aabbdd"; // 0 0:ldc1 #2
// 1 2:astore_1 System.out.println(s); // 2 3:getstatic #3
// 3 6:aload_1 // 4 7:invokevirtual #4
String g = (new StringBuilder()).append("11").append(s).append(5).toString(); // 5 10:new #5
// 6 13:dup // 7 14:invokespecial #6
// 8 17:ldc1 #7
// 9 19:invokevirtual #8
// 10 22:aload_1 // 11 23:invokevirtual #8
// 12 26:iconst_5 // 13 27:invokevirtual #9
// 14 30:invokevirtual #10
// 15 33:astore_2 System.out.println(g); // 16 34:getstatic #3
// 17 37:aload_2 // 18 38:invokevirtual #4
String a = "0"; // 19 41:ldc1 #11
// 20 43:astore_3 for(int i = 1; i < 10; i++) //* 21 44:iconst_1 //* 22 45:istore 4 //* 23 47:iload 4 //* 24 49:bipush 10 //* 25 51:icmpge 80 a = (new StringBuilder()).append(a).append(i).toString(); // 26 54:new #5
// 27 57:dup // 28 58:invokespecial #6
// 29 61:aload_3 // 30 62:invokevirtual #8
// 31 65:iload 4 // 32 67:invokevirtual #9
// 33 70:invokevirtual #10
// 34 73:astore_3 // 35 74:iinc 4 1 //* 36 77:goto 47 System.out.println(a); // 37 80:getstatic #3
// 38 83:aload_3 // 39 84:invokevirtual #4
StringBuilder b = new StringBuilder(); // 40 87:new #5
// 41 90:dup // 42 91:invokespecial #6
// 43 94:astore 4 for(int i = 1; i < 10; i++) //* 44 96:iconst_1 //* 45 97:istore 5 //* 46 99:iload 5 //* 47 101:bipush 10 //* 48 103:icmpge 120 b.append(i); // 49 106:aload 4 // 50 108:iload 5 // 51 110:invokevirtual #9
// 52 113:pop // 53 114:iinc 5 1 //* 54 117:goto 99 System.out.println(b); // 55 120:getstatic #3
// 56 123:aload 4 // 57 125:invokevirtual #12
// 58 128:return } }

这里说一下分析结果。

1、无变量的字符串拼接,在编译期间值都确定了,所以 javac 工具帮我们把它直接编译成一个字符常量。

2、有变量的字符串拼接,在编译期间变量的值无法确定,所以运行期间会生成一个StringBuilder 对象。

3、循环中使用字符串拼接,循环内,每循环一次就会产生一个新的 StringBuilder 对象,对资源有一定的损耗。

4、循环外使用 StringBuilder,循环内再执行 append() 方法拼接字符串,只会成一个 StringBuilder 对象。

因此,对于有循环的字符串拼接操作,建议使用 StringBuilder 和 StringBuffer,对性能会有一定的提升。

其实上面的结论,《阿里巴巴Java开发手册》中有所提到,此文正好与该条结论相对应。

640?wx_fmt=png

一个简单的字符串,用起来确实简单,背后付出了多少工程师的心血,在此,深深地佩服詹爷。

640?wx_fmt=png

号外:最近整理了一下以前编写的一系列Spring Boot内容,整了个《Spring Boot基础教程》的PDF,关注我,回复:001,快来领取吧~!002 资源也即将整理出炉,先关注我吧!随后奉上更多精选学习资料!!!

·END·

 近期热文:

640?wx_fmt=png

看完,赶紧点个“好看”鸭

点鸭点鸭

↓↓↓↓

转载地址:https://didispace-wx.blog.csdn.net/article/details/86611114 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring Cloud Alibaba 基础教程:Nacos 生产级版本 0.8.0
下一篇:Gitlab CI 持续集成的完整实践

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年05月03日 17时03分18秒