走近Java之幕后的String
前几天,有个同事问了我一个表面看起来显而易见的问题,是关于String的,我们一起来看一下(如果有说的不正确的地方,欢迎大家指正)。

java中,字面量在编译期计算,并且String字面量作为常量,存储在方法区中,仅保留一份。带有变量的计算,在运行期执行。那么,str3在执行的时候,发生了什么。
第一步,初始化一个StringBuilder对象,并在构造器中调用父类AbstractStringBuilder的构造器,初始化一个长度16的字符数组


第二步,调用StringBuilder的append()方法,传入变量str1,内部调用父类AbstractStringBuilder的append()方法


在入参不为null的情况下,先调用ensureCapacityInternal()方法,判断拼接后的字符串长度是否超过当前字符数组的长度。如果超过了,就计算一个新的长度,然后创建一个新的数组,将现有数组的值复制给它,

具体扩容规则是,将当前字符数组长度扩容一倍再加2,如果扩容后的数组长度还不够,就和Integer.MAX_VALUE - 8(即MAX_ARRAY_SIZE)比较,如果还不够,则就用拼接后的字符串长度,但是最大也不能超过Integer.MAX_VALUE。(有一个newCapacity <= 0的判断,是考虑到value.length << 1变负数;至于扩容一倍还要+2,个人以为是为了提高性能,普遍计算得出,如果有不同理解,欢迎大家评论)


第三步,调用str.getChars()方法,将入参字符串拼接到现有的字符数组后面,实际操作是调用本地方法
System.arraycopy()。
第四步,记录下字符个数,最后返回当前StringBuilder对象。
第五步,拼接字符串”bbb”,重复第二步到第四步,
最后,调用StringBuilder的toString方法,去掉多余的空字符,返回一个当前累计字符长度的String对象,
其实也是调用本地方法System.arraycopy()。复制一个新的字符数组。正好符合String的不变类特性。



走近Java之幕后的String的更多相关文章
- Java 性能优化之 String 篇
原文:http://www.ibm.com/developerworks/cn/java/j-lo-optmizestring/ Java 性能优化之 String 篇 String 方法用于文本分析 ...
- java.lang.Class.forName(String name, boolean initialize, ClassLoader loader)方法
描述 Java.lang.Class.forName(String name, boolean initialize, ClassLoader loader) 方法返回与给定字符串名的类或接口的Cla ...
- JAVA中int、String的类型转换
int -> String int i=12345;String s="";第一种方法:s=i+"";第二种方法:s=String.valueOf(i); ...
- java内存分配和String类型的深度解析
[尊重原创文章出自:http://my.oschina.net/xiaohui249/blog/170013] 摘要 从整体上介绍java内存的概念.构成以及分配机制,在此基础上深度解析java中的S ...
- Java中区别.toString() ,(String),valueOf()方法
在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object.toString(),(String)要转换的对象,St ...
- Java中如何将String转成Date
Java中如何将String转成Date 最近在开发Json数据反序列化为Java对象的时候发现spring mvc 和 Jackson 对Date类型对支持不是特别好,虽然在Java对象序列化为Js ...
- Exception in thread “main” com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String
String json="A valid json"; Job job = new Gson().fromJson(json, Job.class); Exception in t ...
- MySql系列:中文写入数据库出现错误java.sql.SQLException: Incorrect string value: '\xE5\xxxx' for column 'xxxx' at row 1及其解决方法
在将kft-activiti-demo的数据库连接改为mysql之后,可以正常登陆,但是在新建请假流程的时候出现如下错误: Caused by: java.sql.SQLException: In ...
- 【转】Java魔法堂:String.format详解
Java魔法堂:String.format详解 目录 一.前言 二.重载方法 三.占位符 四.对字符.字符串进行格式化 五.对整数进行格式化 六. ...
随机推荐
- passed into methods by value java专题
java没有引用传递只有按值传递,没有引用传递只有按值传递,值传递.因为Primitive类型的值不能改变,所以method不能更改调用方传的primitive 值.因为method更改的是Primi ...
- Android各版本对应的SDK和JDK版本
原文:Android各版本对应的SDK和JDK版本 一.Android各版本对应的SDK版本: 平台版本 SDK版本 版本名称 Android 8.0 26 Oreo Android 7.1 25 N ...
- 『开发技巧』Python音频操作工具PyAudio上手教程
『开发技巧』Python音频操作工具PyAudio上手教程 0.引子 当需要使用Python处理音频数据时,使用python读取与播放声音必不可少,下面介绍一个好用的处理音频PyAudio工具包. ...
- 用Delphi将数据导入到Excel并控制Excel
一.调用Excel的方法:一般情况下有两种方法调用Excel:1. 直接使用Delphi自带的组件:在Form中分别放入ExcelApplication, ExcelWorkbook和ExcelWo ...
- Qt中使用Boost
编译BOOST库 bjam stage --toolset=qcc --without-graph --without-graph_parallel --without-math --without- ...
- Python标准库(3.x): itertools库扫盲
itertools functions accumulate() compress() groupby() starmap() chain() count() islice() takewhile() ...
- RedHat 7.3+ORACLE 12c RAC 使用udev绑定磁盘
在RedHat 7中,很多命令发生了改变,其中使用udev对磁盘绑定的命令也发生了变更,不再使用start_udev,而是改为了udevadm,下面具体介绍如何使用udev对磁盘进行绑定,这里对6和7 ...
- 了解BroadcastRecever
广播分类: 标准广播(Normal broadcasts):完全异步执行的广播,接收没有先后顺序,效率高,无法被接收器被拦截. 有序广播(Ordered broadcasts) :同步执行的广播,有先 ...
- Ext5.1日期控件仅显示年月
1.注册xtype类型 2.保存文件为xxxx.js 3.使用 xtype : monthfield return this.buildToolbar({ items: [ { xtype: 'mon ...
- 毕设(一)C#的百度api调用
这个学期就要毕业了,选了一个无人机地面站软件设计的题目,这几天也开始着手做, 首先做了一个百度地图的调用,这里因为是上位机的开发,所有就不介绍Javascript的 调用方法,核心是用到一个类Http ...
