本章環境java 1.8
String
字符串拼接會重新生成新的字符串
String a= "123";
String a=a+"123";
代碼及反編譯結果
public class Main{
public static void main(String[] args) {
String str = new String("abc");
}
}
反編譯結果
Constant pool:
#1 = Methodref #7.#16 // java/lang/Object."<init>":()V
#2 = Class #17 // Main
#3 = Methodref #2.#16 // Main."<init>":()V
#4 = Class #18 // java/lang/String
#5 = String #19 // abc
#6 = Methodref #4.#20 // java/lang/String."<init>":(Ljava/lang/String;)V
#7 = Class #21 // java/lang/Object
#8 = Utf8 <init>
#9 = Utf8 ()V
#10 = Utf8 Code
#11 = Utf8 LineNumberTable
#12 = Utf8 main
#13 = Utf8 ([Ljava/lang/String;)V
#14 = Utf8 SourceFile
#15 = Utf8 Main.java
#16 = NameAndType #8:#9 // "<init>":()V
#17 = Utf8 Main
#18 = Utf8 java/lang/String
#19 = Utf8 abc
#20 = NameAndType #8:#22 // "<init>":(Ljava/lang/String;)V
#21 = Utf8 java/lang/Object
#22 = Utf8 (Ljava/lang/String;)V
當new String("abc")時,其實會先在字符串常量區生成一個abc的對象,然後new String()時會在堆中分配空間,然後此時會把字符串常量區中abc複製一個給堆中的String(這裏不是很清楚,是複製還是引用??),故abc應該在堆中和字符串常量區。
StringBuffer&StringBuilder
都是繼承AbstractStringBuilder實現
所以擴容的方式也是利用AbstractStringBuilder的擴容方式,2n+2的方式擴容
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
常用方法
- 獲得某個位置上的字符s.charAt(1)
- 修改某個位置上的字符s.setCharAt(1,'1')
- 後綴字符串s.append("11")
不同點
StringBuffer是線程安全,對大部分方法使用synchronized修飾,如:append方法
StringBuilder是線程不安全