java提供利用"+"进行字符串直接拼接的功能,如以下示例:
String provice = "Jiang Su";
String city = "Nan Jing";
String address = provice + city;
那么代码第三句,究竟做了什么呢?我们利用vim编写一个StringConcat类,代码如下:
public class StringConcat {
public static void main(String[] args) {
String province = "Jiang Su";
String city = "Nan Jing";
String address = province + city;
}
}
在JDK 1.8.0_151环境下,使用javac编译该源文件,执行命令为【javac StringConcat.java】(文中所有命令都是在windows7 cmd环境下执行,并且使用到了JDK自带的工具,读者如果要试验,请务必确保已经安装了JDK,并且配置了java环境变量)得到StringConcat.class字节码文件。使用javap工具反编译StringConcat.class文件,执行【javap -c StringConcat.class】命令:
看到这里我们会有一点奇怪,为什么会出现java.lang.StringBuilder类,而且还调用了它的append和toString方法。
进一步直观的展示,我们采用IDEA进行反编译,得到如下反编译后的代码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
public class StringConcat {
public StringConcat() {
}
public static void main(String[] var0) {
String var1 = "Jiang Su";
String var2 = "Nan Jing";
(new StringBuilder()).append(var1).append(var2).toString();
}
}
这样一看,就很明了了,原来String的字符串“相加”(拼接)其实是new了一个StringBuilder对象,并执行其append方法实现拼接,最后通过其toString方法返回一个字符串对象。(至于源代码中的String address对象去哪儿了,我会在其他文章专门讲解)
【总结】:String的+(拼接)其实是利用了StringBuilder的append方法,可以说是java的一个语法糖。
【思考】:如果在循环中,使用String的+,每次都new出一个StringBuilder对象,岂不是很耗费资源。所以,如果是线程安全的环境,那么建议直接使用StringBuilder的append方法来代替字符串的拼接。
【问题】:文中的反编译是在JDK1.8以及以前版本中的结果,如果放到JDK1.9环境下呢?还是这个结果吗?可以提示读者一下,JDK1.9在java.lang.invoke包下,新增了一个StringConcatFactory类,猜猜看这和String的+有什么关系呢?