In-depth understanding of the similarities and differences between the three classes String, StringBuffer and StringBuilder

Java provides three classes for handling strings, respectively, String, StringBuffer and StringBuilder. StringBuilder which is jdk1.5 just introduced.

These three classes what difference does it? What are their usage scenario is it?

Code for this article is running on the jdk12, jdk12 and jdk5, jdk8 a big difference, especially String, StringBuffer and implementation of StringBuilder.

Type and value jdk5 jdk8 in String class is char [], to jdk12, value type to byte [].

jdk5, JDK6 constant pool is on the permanent generation, and the permanent generation of Java heap are two completely separate areas.

To jdk7 and later,

Let's look at these three classes of source code.

String class section Source:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence,
               Constable, ConstantDesc {

    @Stable
    private final byte[] value;
    
    public String(String original) {
        this.value = original.value;
        this.coder = original.coder;
        this.hash = original.hash;
    }
    public native String intern();

String class modified by the final qualifier, so the String class is immutable, objects once created, can not be changed.

String class member variable byte array has a value of this variable is used to store the contents of the string, is modified with a final, once initialized, can not be changed.

java provides two main ways to create a string:

//方式1
String str = "123";
//方式2
String str = new String("123");

java virtual machine specification defines strings are stored in a string constant pool, whether created with Mode 1 or Mode 2 strings, looks up from the pool to a string constant, if it already exists, direct return, or the creation of the return.

java compiler when compiling java class encountered "abc", "hello" this string constant, the constant regions will be a constant in these classes, class loading, the string is added to a constant string constants pool.

String constant containing the expression, not be placed at compile time constant region, e.g., String str = "abc" + a

The maximum effect of constant pool is shared use, improve the efficiency of program execution.

Look at a few cases below.

Case 1:

1  String str1 = "123";
2  String str2 = "123";
3  System.out.println(str1 == str2);

The results of running the above code is true.

When you run the first line of code, now create a string constant pool 123 objects, and then assigned to the variable str1.

Running the second line, it has been found that the presence of the constant pool 123 subject, return address 123 directly to the variable object str2.

str1 and str2 variable points to the address, they are the same object, and therefore the results of running to true.

As can be seen from the figure, using str1 "" quotes (and usually the amount of said literal) creates a string, it is determined whether the constant pool for the presence of the string at compile time, if there is no direct return create objects rEFERENCE; if not, then create the instance in the string constant pool reference to the instance back to str1.

Case 2:

1  String str1 = new String("123");  
2  String str2 = new String("123");
3  String str3 = new String(str2);
4  System.out.println((str1==str2));  
5  System.out.println((str1==str3));

6  System.out.println((str3==str2));  

The results of the above code is run

false
false
false

As can be seen from the figure, the first line of code, when executed, creates two objects, a character string stored in the constant pool, the presence of a stack, there is a reference to the object stored in the stack str1.

When performing the second line, the existing string constant pool "123" objects in the heap so only creates a String object, and the object points to the address the constant pool "123" address of the object, while the stack create an object reference str2, a reference to an object address heap created.

The implementation of the third line of code, in heap create a string object that points to the memory address of the variable str2 to perform memory address.

String objects created by the new way will open up a new space in the heap memory for objects stored string constant pool.

For the object, whether the operation is a comparison == two exclusive memory address match, the result of execution of the above code is false.

Case 3:

//这行代码编译后的效果等同于String str1 = "abcd";
String str1 = "ab" + "cd";  
String str2 = "abcd";   
System.out.println((str1 == str2)); 

The results of the implementation of the above code: true.

Use a string containing the constant connection is also created constant, the compiler can determine the period, when the class is loaded directly into the string constant pool, of course, also need to determine whether the string constant pool already exists that string.

Case 4:

String str2 = "ab";  //1个对象  
String str3 = "cd";  //1个对象                                         
String str4 = str2 + str3 + “1”;                                        
String str5 = "abcd1";    
System.out.println((str4==str5)); 

The results of the implementation of the above code: false.

When "+" is connected to the string contains a variable, the value of the variable is to be determined at runtime.

If you are using jdk8 previous version of a virtual machine, when the string concatenation will generate heap jvm StringBuilder object by calling the append method concatenate strings, toString method StringBuilder last call stack to generate the final string object in jvm.

By looking at the bytecode you can know before jdk8 version of "+" string concatenation when implemented through StringBuilder. By looking at the byte code can be known, as shown below:

And if you are using jdk9 later version of the virtual machine, the virtual machine is calling comes InvokeDynamic string concatenation and saved in the heap. Byte code as follows:

str4 objects in a string constant pool, str5 object on the heap, so they are not the same object, so the result returned is false.

Case 5:

String s5 = new String(“2”) + new String(“3”);

Case 4 and the same, because new String ( "2") creates a string, but also at run time to determine the object memory address, and 4 cases of same.

Case 6:

final String str1 = "b";  
String str2 = "a" + str1;  
String str3 = "ab";  
System.out.println((str2 == str3)); 

Code execution result of the above is true.

str1 variable is constant, it is determined at compile time, directly into the string constant pool, the same effect as the above code:

String str2 = "a" + "b";
String str3 = "ab";
System.out.println((str2 == str3));

String class calls the intern () method, examples of the string to the string will be placed in the stack constant pool.

Case 7:

String str2 = "ab";
String str3 = "cd";
String str4 = str2 + str3 + "1";
str4.intern();
String str5 = "abcd1";
System.out.println((str4==str5));

The results of the implementation of the above code: true. After calling str4.intern () method to put the str4 string constant pool, and the same is str5 instance.

StringBuffer part of the source code:

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
{

StringBuilder part of the source code:

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
{

Visible StringBuffer and StringBuilder inherit AbstractStringBuilder class.

AbstractStringBuilder source category:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    byte[] value;

AbstractStringBuilder member also has a byte array variable value, the variable value stored for the string, with the final variable is not modified, it can be changed, and this is the biggest difference between String.

When calling the append method, dynamically increase the size of the byte array variable value.

StringBuffer and StringBuilder function is the same, is to improve the efficiency of java in the connection string, because the direct use + string concatenation, then, jvm will create multiple String objects, so a certain amount of overhead. AbstractStringBuilder a byte array used to hold the string needs to append, a byte array has an initial size, when the current exceeds the string length append char array capacity, the dynamic expansion of the byte array, i.e. a greater re-apply period memory space, and then copied to the new array bute current location, and copied as memory reallocation overhead is relatively large, so that each re-application mode memory space is greater than the current application requires the use of memory space, where two times.

The biggest difference between StringBuffer and StringBuilder StringBuffer is thread-safe, but StringBuilder is not thread-safe, two classes from their source can know, in front of the class StringBuffer methods are synchronized modifier.

String Once the assignment can not be changed after instantiation or, if the new value will be given to re-open the memory address for storage.

StringBuffer and StringBuilder classes while using a method such as changing the insert and append string values ​​except for continuous operation on the memory address of the original object storage, reducing overhead resources.

Summary:
1, frequently using the "+" character splicing operation, replaced by append method StringBuffer and StringBuilder class implementation.

2, a large number of splicing StringBuffer string operations using multi-threaded environment, thread-safe StringBuffer;

3, a lot of string concatenation use StringBuilder operating under the single-threaded environment, StringBuilder is not thread-safe.

Guess you like

Origin www.cnblogs.com/airnew/p/11628017.html