老板扣了我1000,因为我没记住阿里巴巴开发手册的这条规则。
来源:Java面试那些事儿
本文故事构思来源于脉脉上的一篇帖子“一行代码引发的血案”。
其实关于字符串的文章,我之前也写过一篇《诡异的字符串问题》,字符串对于我们开发者而言,可以用最近很流行的一句话“用起来好嗨哟,仿佛人生达到了巅峰”。
确实大家都用的很嗨,很便利,但 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 <Method void Object()> // 2 4:return } public static void main(String args[]) { String s = "aabbdd"; // 0 0:ldc1 #2 <String "aabbdd"> // 1 2:astore_1 System.out.println(s); // 2 3:getstatic #3 <Field PrintStream System.out> // 3 6:aload_1 // 4 7:invokevirtual #4 <Method void PrintStream.println(String)> String g = (new StringBuilder()).append("11").append(s).append(5).toString(); // 5 10:new #5 <Class StringBuilder> // 6 13:dup // 7 14:invokespecial #6 <Method void StringBuilder()> // 8 17:ldc1 #7 <String "11"> // 9 19:invokevirtual #8 <Method StringBuilder StringBuilder.append(String)> // 10 22:aload_1 // 11 23:invokevirtual #8 <Method StringBuilder StringBuilder.append(String)> // 12 26:iconst_5 // 13 27:invokevirtual #9 <Method StringBuilder StringBuilder.append(int)> // 14 30:invokevirtual #10 <Method String StringBuilder.toString()> // 15 33:astore_2 System.out.println(g); // 16 34:getstatic #3 <Field PrintStream System.out> // 17 37:aload_2 // 18 38:invokevirtual #4 <Method void PrintStream.println(String)> String a = "0"; // 19 41:ldc1 #11 <String "0"> // 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 <Class StringBuilder> // 27 57:dup // 28 58:invokespecial #6 <Method void StringBuilder()> // 29 61:aload_3 // 30 62:invokevirtual #8 <Method StringBuilder StringBuilder.append(String)> // 31 65:iload 4 // 32 67:invokevirtual #9 <Method StringBuilder StringBuilder.append(int)> // 33 70:invokevirtual #10 <Method String StringBuilder.toString()> // 34 73:astore_3 // 35 74:iinc 4 1 //* 36 77:goto 47 System.out.println(a); // 37 80:getstatic #3 <Field PrintStream System.out> // 38 83:aload_3 // 39 84:invokevirtual #4 <Method void PrintStream.println(String)> StringBuilder b = new StringBuilder(); // 40 87:new #5 <Class StringBuilder> // 41 90:dup // 42 91:invokespecial #6 <Method void StringBuilder()> // 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 <Method StringBuilder StringBuilder.append(int)> // 52 113:pop // 53 114:iinc 5 1 //* 54 117:goto 99 System.out.println(b); // 55 120:getstatic #3 <Field PrintStream System.out> // 56 123:aload 4 // 57 125:invokevirtual #12 <Method void PrintStream.println(Object)> // 58 128:return }}
这里说一下分析结果。
1、无变量的字符串拼接,在编译期间值都确定了,所以 javac 工具帮我们把它直接编译成一个字符常量。
2、有变量的字符串拼接,在编译期间变量的值无法确定,所以运行期间会生成一个StringBuilder 对象。
3、循环中使用字符串拼接,循环内,每循环一次就会产生一个新的 StringBuilder 对象,对资源有一定的损耗。
4、循环外使用 StringBuilder,循环内再执行 append() 方法拼接字符串,只会成一个 StringBuilder 对象。
因此,对于有循环的字符串拼接操作,建议使用 StringBuilder 和 StringBuffer,对性能会有一定的提升。
其实上面的结论,《阿里巴巴Java开发手册》中有所提到,此文正好与该条结论相对应。
一个简单的字符串,用起来确实简单,背后付出了多少工程师的心血,在此,深深地佩服詹爷。
号外:最近整理了一下以前编写的一系列Spring Boot内容,整了个《Spring Boot基础教程》的PDF,关注我,回复:001,快来领取吧~!002 资源也即将整理出炉,先关注我吧!随后奉上更多精选学习资料!!!
·END·
近期热文:
SpringCloudAlibaba基础教程:使用Nacos实现服务注册与发现
“三次握手,四次挥手”你真的懂吗?
“拼多多”被薅的问题出在哪儿?损失将如何买单?
在前后端分离的路上承受了多少痛?看看这篇是否能帮到你?
你真的会高效的在GitHub上搜索开源项目吗?
Spring Boot:自定义starter
中台是个什么鬼?
从业务到平台的思维转变
是什么使你留在你的公司
重磅!Github 开放无数量限制的免费私有仓库!
百度面试题:求数组最大值
看完,赶紧点个“好看”鸭
点鸭点鸭
↓↓↓↓
老板扣了我1000,因为我没记住阿里巴巴开发手册的这条规则。相关推荐
- 漫画:老板扣了我1000,因为我没记住阿里巴巴开发手册的这条规则。
本文故事构思来源于脉脉上的一篇帖子"一行代码引发的血案". 其实关于字符串的文章,我之前也写过一篇<诡异的字符串问题>,字符串对于我们开发者而言,可以用最近很流行的一句 ...
- 老版本微信平台服务器部署步骤(没那么坑版)
老版本微信平台服务器部署步骤(没那么坑版) By Levy 1. 用putty登陆服务器 2. 安装需要的程序(nginx/python/pip/virtualenv) 3. 使用virtual ...
- 苦逼的是怎么又有东西没记住,但我们依然每天坚持一遍、一遍又一遍指导记住为止。
期待的是可以检验自己学习的成功:苦逼的是怎么又有东西没记住,但我们依然每天坚持一遍.一遍又一遍指导记住为止. 原本以为大家会把讲过的都记录下来,以便日后毕业复习,事实证明18岁的我还是太年轻. 一切想 ...
- 都1202年了,阿里五岳版的《Java开发手册》你还没拜读过?
都2021年了相信有很多人已经看过阿里五岳版的<Java开发手册>了! 没看过也没有关系,因为我今天给大家分享出来这份阿里开发手册五岳版的核心总结篇! 如果想获取开发手册的话可以直接添加助 ...
- 都说DBA 是越老越值钱, 那你是没干过DBA
正式干DBA 也是有些年头了,十几年是有了, 前些日子翻出最早买的一本数据库的书是2001年的.这么多年,身边的开发,项目经理,应用运维等等这些"友人", 说的最多的一句话就是, ...
- 做自媒体值实用的九个网站,身为老司机的你你用过没?
嗨咯,大家好,这里依旧为自媒体人推送你所想了解的平台运营方法技巧,在前面我们已经讲到了百家号的注册以及运营的小技巧,在这里给大家分享几个好用又实用的网站,希望对你们有帮助哦~ 作为一个自媒体人,内容素 ...
- 油腻老爷们,你是有多久没化过妆了?
因为有些需求[原因在文末],需要拍一张正装照. 我已经受够了那些小摄像馆拍的照片了, 完全拍不出我的神韵! 效果还不如我手机开个美颜! 生活问题,有时候问邻居效率很高! 在小区群里,问了一下邻居! 立 ...
- 阿里巴巴总市值超过4000亿美元,“股神”巴菲特:没买阿里巴巴股票是个错误!...
7月27日晚间,美股上市的阿里巴巴(NYSE:BABA)总市值突破4000亿美元,截至发稿股价上涨1.81%,报于每股158.92美元,总市值达到4070亿美元. 在最近的一档访谈节目中,现年87 ...
- 该终端已停用_宣杭老线停用,勾庄、三墩、仓前、老余杭、瓶窑三千多亩地待开发...
一 周 速 递 1.时隔120多天,主城区土拍1月5日重启 2.杭州地铁7号线首通段开通倒计时 3.杭州地铁6号线预计年底通车 4.宣杭老线今日正式停用 5.崇贤-老余杭连接线高架桥预计明年竣工 6. ...
最新文章
- meson 中调用shell script
- IOS入门-TargetAction
- 吴恩达 coursera AI 专项四第三课总结+作业答案
- Git出现Unable to create 'E:/xxx/.git/index.lock': File exists.的解决办法
- 招行率先落地房贷新政 其他银行细则仍在制定
- 大数据安全分析有哪些常见问题
- 黑链-最高明的网站隐藏链接方法
- lumion制作海上明月5.29
- php项目过段时间就崩溃,apache 运行一段时间出现错误
- mysql 插入多条值_mysql一次性插入多条数据
- Python编程快速上手-让繁琐工作自动化 — 读书与代码笔记
- 2021年全球高级相变材料(PCM)收入大约1513.7百万美元,预计2028年达到3220.4百万美元
- 课程设计实验--火车票座位分配
- vue3中组件给后代组件传值,provide和inject的使用
- 位图(BMP)文件格式(一)
- 少儿编程和机器人编程哪个更好一点
- 华为区块链白皮书(一)
- 【逐梦旅程Windows游戏编程学习笔记 ①】基本GDI绘图
- 几天时间【免费】搭建了自己的个人博客,免租服务器,免买域名,真香警告。
- 搜索与图论1—深搜、宽搜、拓扑排序