参考答案
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—