String string constant
StringBuffer string variable (thread-safe)
StringBuilder string variable (non-thread-safe)
Briefly, the main performance difference between the String type and the StringBuffer type is that String is an immutable object, so in every Every time you change the String type, it is actually equivalent to generating a new String object, and then pointing the pointer to the new String object. Therefore, it is best not to use String for strings that frequently change content, because each time an object is generated, it will cause harm to the system. Performance will be affected, especially when there are too many unreferenced objects in the memory, the JVM's GC will start to work, and the speed will definitely be quite slow.
If you use the StringBuffer class, the result will be different. Each time the result will operate on the StringBuffer object itself, instead of generating a new object and then changing the object reference. So in general we recommend using StringBuffer, especially when string objects change frequently. In some special cases, the string concatenation of String objects is actually interpreted by the JVM as the concatenation of StringBuffer objects, so in these cases the speed of String objects will not be slower than that of StringBuffer objects, and especially the following string objects are generated Among them, String efficiency is much faster than StringBuffer:
String S1 = “This is only a” + “simple” + “test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple ").append(" test");
You will be surprised to find that the speed of generating String S1 objects is simply too fast, and at this time StringBuffer does not have an advantage at all in speed. In fact, this is a trick of the JVM. In the eyes of the JVM, this
String S1 = “This is only a” + “simple” + “test”; is actually:
String S1 = “This is only a simple test”; so Of course it doesn't take much time. But what everyone should note here is that if your string comes from another String object, the speed will not be that fast, for example:
String S2 = “This is only a”;
String S3 = “simple”;
String S4 = "test";
String S1 = S2 +S3 + S4;
At this time, the JVM will do it in the original way
In most cases StringBuffer > String
StringBuffer
Java.lang. StringBuffer thread-safe mutable character sequence. A string buffer similar to String, but cannot be modified. Although it contains a specific sequence of characters at any point in time, the length and content of that sequence can be changed through certain method calls.
String buffers can be used safely with multiple threads. These methods can be synchronized when necessary, so that all operations on any particular instance appear to occur in a serial order consistent with the order of method calls made by each thread involved.
The main operations on StringBuffer are the append and insert methods, which can be overloaded to accept any type of data. Each method effectively converts the given data into a string and then appends or inserts the characters of that string into a string buffer. The append method always adds these characters to the end of the buffer; the insert method adds characters at a specified point.
For example, if z refers to a string buffer object whose current content is "start", then calling z.append("le") by this method will cause the string buffer to contain "startle", while z.insert(4, "le") will change the string buffer to contain "starlet".
In most cases StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder A variable character sequence is new in 5.0. This class provides a StringBuffer-compatible API but does not guarantee synchronization. This class is designed as a drop-in replacement for StringBuffer when the string buffer is used by a single thread (which is a common situation). It is recommended to prefer this class if possible, as it is faster than StringBuffer in most implementations. The methods for both are basically the same.
==================================================== ========================
Detailed explanation of String class
1. String class is final and cannot be inherited.
2. The essence of String class is character array char[], and its value cannot be changed. PRivate final char value[];
Then open the API document of the String class, you can find:
3. String class objects have a special way to create, which is to directly specify, for example, String x = "abc", "abc" represents a String object. And x is the address of the "abc" object, also called
as a reference to the "abc" object.
4. String objects can be concatenated through "+". After concatenation, a new string is generated. You can also concatenate through concat(), which will be described later.
6. Java will maintain a String Pool when running. The JavaDoc translation is very vague as "string buffer". String pool is used to store various strings generated during runtime,
And the contents of the strings in the pool are not repeated. This buffer pool does not exist for general objects, and the created objects only exist in the stack area of the method.
5. There are many ways to create strings, which can be summarized into three categories:
First, use the new keyword to create a string, such as String s1 = new String("abc");
Second, specify it directly. For example, String s2 = "abc";
Third, use concatenation to generate a new string. For example, String s3 = "ab" + "c";
2. Creation of String Object
Creation of String object is also very particular. The key is to understand its principle.
Principle 1: When using any method to create a string object s, the Java runtime (running JVM) will take this Then create a string s in the pool, otherwise, do not add it to the pool.
Principle 2: In Java, as long as you use the new keyword to create an object, a new object will definitely be created (in the heap area or stack area).
Principle 3: If you use direct specification or pure string concatenation to create a String object, only the strings in the String pool will be checked and maintained. If there is no string in the pool, create one in the pool, otherwise
! But the String object will never be created in the stack area.
Principle 4: Using an expression containing variables to create a String object will not only check and maintain the String pool, but also create a String object in the stack area.
In addition, the intern() method of String is a local method, defined as public native String intern(); the value of the intern() method is to allow developers to focus on the
String pool. When the intern method is called, if the pool already contains a string equal to this String object (as determined by the equals(Object) method), the string in the pool
is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
3. Immutable Classes
Immutable strings have a big advantage: the compiler can set the string to be shared.
Immutable String classes have an important advantage - they are not shared references.
That’s it. In order to improve efficiency, JAVA has done special processing for the String type - providing a string pool for the string type.
There are two ways to define a string type variable:
string name= "tom ";
string name =new string( "tom ")
When you use the first method, you use the string pool.
When you use the second method, it is an ordinary way of declaring objects
If you use the second method One way, then when you declare a string whose content is also "tom", it will use the original memory in the string pool without reallocating the memory. In other words, string saname = "tom ", will Pointing to the same memory
In addition, regarding the issue that the string type is immutable:
The string type is immutable, that is to say, when you want to change a string object, such as name = "madding "
Then the virtual machine will not Change the original object, but generate a new string object, and then let name point to it. If the original "tom" does not have any object to refer to it, the virtual machine's garbage collection mechanism will receive it.
It is said that this can improve efficiency! ! !
==================================================== ========================final StringBuffer a = new StringBuffer("111");
final StringBuffer b = new StringBuffer("222");
a=b;//This sentence does not pass the compilation
final StringBuffer a = new StringBuffer("111");
a.append("222");//The compilation passes
It can be seen that final only applies to the referenced "value" ( That is, the memory address) is valid, which forces the reference to only point to the object initially pointed to. Changing its pointing will cause a compile-time error. As for changes in the object it points to, final is not responsible.
Four examples of String constant pool problems
The following is a comparative analysis and understanding of several common examples:
[1]
String a = "a1";
String b = "a" + 1;
System.out .println((a == b)); //result = true
String a = "atrue";
String b = "a" + "true";
System.out.println((a == b)) ; //result = true
String a = "a3.4";
String b = "a" + 3.4;
System.out.println((a == b)); //result = true
Analysis: JVM will optimize the "+" connection of string constants into the value after the connection during program compilation. Take "a" + 1 as an example, after compiler optimization Afterwards, it is already a1 in class. The value of its string constant is determined during compilation, so the final result of the above program is true.
[2]
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println((a == b)); //result = false
Analysis: For string references, JVM has a string reference in the "+" connection of the string, and the value of the reference cannot be determined during program compilation, that is, "a" + bb cannot be used by the compiler Optimization, only dynamically allocate and assign the new address after connection to b during program running. So the result of the above program is false.
[3]
String a = "ab";
final String bb = "b";
String b = "a" + bb;
System.out.println((a == b)); //result = true
Analysis: The only difference from [3] is that the bb string is final modified. For the final modified variable, it is parsed into a local copy of the constant value at compile time and stored in its own constant pool or embedded. into its bytecode stream.
So the effect of "a" + bb and "a" + "b" at this time is the same. Therefore, the result of the above program is true.
[4]
String a = "ab";
final String bb = getBB();
String b = "a" + bb;
System.out.println((a == b)); //result = false
private static String getBB() { return "b"; }
Analysis: JVM cannot determine the value of string reference bb during compilation. Only after calling the method during program running, the return value of the method and "a" is used to dynamically connect and assign the address to b, so the result of the above program is false.
It can be concluded from the above 4 examples:
String s = "a" + "b" + "c"; It is equivalent to String s = "abc";
String a = "a";
String b = "b";
String c = "c";
String s = a + b + c;
This is different, the final result is equal to:
StringBuffer temp = new StringBuffer();
temp. append(a).append(b).append(c);
String s = temp.toString();
From the above analysis results, it is not difficult to infer that the reason why String uses the connection operator (+) is inefficient , the code looks like this:
public class Test {
public static void main(String args[]) {
String s = null;
for(int i = 0; i < 100; i++) { s += "a"; }
}
}
Every time you do +, a StringBuilder object is generated, and then thrown away after appending. The next time the loop arrives, a StringBuilder object is regenerated, and then the string is appended, and this loop continues until the end. If we directly use the StringBuilder object for append, we can save N - 1 times of creating and destroying objects. Therefore, for applications that require string concatenation in a loop, StringBuffer or StringBulider objects are generally used for append operations.
Understanding and analysis of intern method of String object
public class Test4 {
private static String a = "ab";
public static void main(String[] args){
String s1 = "a";
String s2 = " b";
String s = s1 + s2;
System.out.println(s == a);//false
System.out.println(s.intern() == a);//true
}
}
The use of Java here is a constant pool issue. For the s1+s2 operation, a new object is actually created in the heap. s saves the content of this new object in the heap space, so the values of s and a are not equal. When the s.intern() method is called, the address value of s in the constant pool can be returned. Because the value of a is stored in the constant pool, the values of s.intern and a are equal.