String, StringBuilder, StringBuffer source analysis
String source
private final char value[];
public String(a) {
this.value = "".value;
}
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
Copy the code
As you can see from the graph, strings are composed of char arrays with the final keyword, which means that objects of type String cannot be changed.
String a = "abc";
a = a + "d";
System.out.println(a);
StringBuffer buffer = new StringBuffer();
buffer.append("a");
System.out.println(buffer);
StringBuilder builder = new StringBuilder();
builder.append("b");
System.out.println(builder);
Copy the code
The Java virtual machine creates a String a and assigns the value of “D” to the new String A. The Java virtual machine’s garbage collection (GC) collects the original A, so the String is not actually changed. As you can see, it is not recommended to use String for frequently manipulated strings. This is a slow process of constantly creating new objects and reclaiming old ones.
String + operation principle
public static void main(String[] args) {
int num = 10;
String a = "abc";
long time = System.currentTimeMillis();
String b = "hello world";
for (int i = 0; i < num; i++) { a = a + b; System.out.println(a); }}Copy the code
In JDK9 and earlier, String + operations are implemented by building a StringBuilder object and calling the object’s append() method.
JDK11, decomcompiled:
// As of JDK 9, string concatenation operations are compiled to use the Invokedynamic directive. Java invokedynamic instruction using the boot method. Lang. Invoke. StringConcatFactory. MakeConcatWithConstants
// Use jDK11 to decompress the code
public static void main(final String[] args) {
final int num = 10;
String a = "abc";
final long time = System.currentTimeMillis();
for (int i = 0; i < num; ++i) { a = invokedynamic(makeConcatWithConstants:(Ljava/lang/String;) Ljava/lang/String; , a);// Notice hereSystem.out.println(a); }}Copy the code
StringBuffer source
public class StringBuffer extends AbstractStringBuilder{
// char arrays hold characters
char[] value;
public StringBuffer(a) {
// The default initial capacity is 16
super(16); }}Copy the code
As you can see from the source code, the underlying StringBuffer is also a char array. StringBuffer default initial space is 16. For StringBuffer expansion, as you can see from the figure below, it’s twice the size of the old array, plus 2.
Let’s take a look at the append function of a StringBuffer, which is thread-safe and is modified by synchronized.
The StringBuilder source
A comparison with the source code for StringBuffer shows that the underlying array is also a char array, and the initial space is 16. Both StringBuilder and StringBuffer are derived from AbstractStringBuilder, so the initial space and expansion are the same.
public final class StringBuilder
extends AbstractStringBuilder {
// char arrays hold characters
char[] value;
public StringBuilder(a) {
// The default initial capacity is 16
super(16); }}Copy the code
The difference between StringBuilder and StringBuffer can be seen in the picture below. For the append() method, the lack of synchronized qualifiers makes StringBuilder not thread-safe.
conclusion
String length size immutable StringBuffer and StringBuilder Length variable StringBuffer thread safety StringBuilder thread safety therefore: String: Applicable to the situation of the small amount of string manipulation StringBuilder: is suitable for the single thread of the character buffer in a large number of operating StringBuffer: apply multithreading in character buffer under a large number of operating conditions