String代表字符串的类,最终类---字符串是一个常量,定义好之后不能改变,即指常量池中储存的地址不能改变;
因为字符串是常量,所以可以被共享。
字符串在Java底层是以数组形式存储在堆中的,如String str = “abc” -> final char[] data = {‘a’, ‘b’, ‘c’}
String str1="ab" str1直接指向常量池中的字符串地址------这里产生1个对象
String str2=new String("ab") str2先指向String对象,对象中储存着指向常量池中的字符串地址------这里产生2个对象
String str3 = "a";
str3 += "b"; -->str3=str3+"b"-->str3=new StringBuilder(Str3).append("b").toString()
------这里产生5个对象
1.堆中生成"a",str3指向代表该字符串a的常量池中的地址
2.在堆中生成一个StringBuilder对象,储存着"a"的代表该字符串a的常量池中的地址
3.生成"b"
4.生成"ab"
5.产生字符串对象"ab"
例题:
已经定义好了一个字符串数组arr,包含了100个字符串, 如果需要把这100个字符串拼接成1个字符串,使用+会额外产生多少个对象?
String result = “”; // 1
for(String str : arr){
result += str; // 每拼接一次,就要额外产生3个对象。100 --- 300
}
// 整个过程中,要额外产生301个对象
// 如果使用StringBuilder直接拼接结果,额外产生多少个对象?
StringBuilder sb = new StringBuilder(); // 1
for(String str : arr){
sb.append(str); // append一次,产生1个对象 100 --- 100
}
String str = sb.toString(); // 1
// 整个过程中,要额外产生102个对象
所以如果拼接多个字符串的话,建议使用StringBuilder
StringBuilder是一个线程不安全的类,StringBuffer是一个线程安全的类