参考答案
String底层是一个不可变字符串,使用连接符时,经过了StringBuilder的优化处理,不是在原来的String对象中做追加。
源码实例及剖析:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[];
private int hash; // Default to 0
private static final long serialVersionUID = -6849794470754667710L;
......此处省略N多代码
/**
* Initializes a newly created {@code String} object so that it represents
* the same sequence of characters as the argument; in other words, the
* newly created string is a copy of the argument string. Unless an
* explicit copy of {@code original} is needed, use of this constructor is
* unnecessary since Strings are immutable.
*
* @param original
* A {@code String}
*/
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
}
可见,String类是final修饰的,成员属性 value也是final的,并且是一个char类型的数组,传递的参数值直接赋值给了value。
这说明了String是一个不可变字符串,底层是一个char类型的数组。
实际上,我们经常这样写 String a = “abc”; 此时声明的变量值在常量池中。
有的同学也许会问,String里面不是可以使用+连接符来进行String的拼接吗?
确实,我们可以使用 “+” 来拼接字符串,但是,这里 JKD的虚拟机做了优化,并不是表面所见的使用连接符,对原来的String做了拼接。
接下来,了解它是如何进行编译的:
public class Test{
public static void main(String [] args){
String str = "abc";
String str1= "def";
str = str+str1;
System.out.println(str);
}
}
在控制台中通过 javac 编译,然后通过java执行,看到结果是 “abcdef”,这里的str到底是否被改变,可以看下编译后的class字节码文件。

通过 javap -c Test 来观察:

结果如下:
- Code的第0、第3标识处,是我们声明的变量值 “abc”和”def”;
- 在Java中的代码使用了 “+” 连接符号,此处看到 Code 第6 处new StringBuilder;
- Code的第14、第18,使用了StringBuilder的append(),得出结论,在使用String时使用连接符,并不是表面看到的直接操作原来的变量做值的拼接,而是使用的StringBuilder对象追加的内容;
- Code的21处,有一个toString()方法,是把当前StringBuilder的对象变成了String。
结论:String底层是一个不可变字符串,使用连接符时,经过了StringBuilder的优化处理,不是在原来的String对象中做追加。
以上,是Java面试题【String的底层实现是怎样的】的参考答案。
输出,是最好的学习方法。
欢迎在评论区留下你的问题、笔记或知识点补充~
—end—
