Don’t know if you have such experience, is not neutral in a industry face, and then browse to it for a long time, I am such, inadvertently today, CTRL + click, point source into a string, just do not have what matter, this afternoon is inside see, unexpectedly, slow to come next time, is my colleague took me to let me to have a meal, Ha ha ha, but the good thing is that I have also sorted out some String knowledge points and shared them with you. I’m sorry if I didn’t sort them out well. The best way to learn about a class is to look at its implementation source code. Take a look at the source code for the class public final class String

implements java.io.Serializable, Comparable<String>, CharSequence{ /** The value is used for character storage. */ private final char value[]; /** The offset is the first index of the storage that is used. */ private final int offset; /** The count is the number of characters in the String. */ private final int count; /** Cache the hash code for the string */ private int hash; // Default to 0 /** Use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L; .

String is final. This means that String cannot be inherited and that its member methods are final by default. In Java, classes decorated with final are not allowed to be inherited, and member methods in the class are final by default. Char char char char char char char char char char char char char char char char char char Public String substring(int beginIndex, int endIndex) {public String substring(int beginIndex, int endIndex) {

if (beginIndex < 0) {
    throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
    throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
    new String(offset + beginIndex, endIndex - beginIndex, value);

}

public String concat(String str) {

int otherLen = str.length();
if (otherLen == 0) {
    return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);

}

public String replace(char oldChar, char newChar) {

if (oldChar ! = newChar) { int len = count; int i = -1; char[] val = value; /* avoid getfield opcode */ int off = offset; /* avoid getfield opcode */ while (++i < len) { if (val[off + i] == oldChar) { break; } } if (i < len) { char buf[] = new char[len]; for (int j = 0 ; j < i ; j++) { buf[j] = val[off+j]; } while (i < len) { char c = val[off + i]; buf[i] = (c == oldChar) ? newChar : c; i++; } return new String(0, len, buf); } } return this;

} As can be seen from the above three methods, neither the sub, concat, or replace operation operates on the original string, but instead regenerates a new string object. That is, after doing this, the original string is not changed. It is important to always remember that a String is immutable once it is created. Any changes to the String do not affect the original object, and any associated change operations generate a new object. We know that string allocation, like any other object allocation, takes a lot of time and space, and we use a lot of strings. In order to improve performance and reduce memory overhead, the JVM has made some optimizations when instantiating strings: it uses a pool of string constants. Whenever we create a string constant, the JVM first checks the string constant pool, and if the string already exists in the constant pool, then flows the transaction directly back to the instance reference in the constant pool. If the string does not exist in the constant pool, the string is instantiated and placed in the constant pool. Because of the immutability of strings, we can be pretty sure that no two strings are the same in the constant pool (this is important to understand above). Constant pools in Java actually come in two forms: static constant pools and run-time constant pools. The so-called static constant pool is the constant pool in *.class files. The constant pool in class files contains not only string (number) literals, but also information about classes and methods, occupying most of the space in class files. After class loading, the JVM virtual machine loads the class file’s constant pool into memory and stores it in the method area. The runtime constant pool is the constant pool in the method area. String a = “chenssy”; String a = “chenssy”; String b = “chenssy”; A, B, and literally Chenssy all point to the “Chenssy” object in the JVM string constant pool. They all point to the same object. String c = new String(“chenssy”); The new keyword must produce an object called Chenssy (note that Chenssy is different from the Chenssy above), and this object is stored in the heap. So two objects should have been generated: C in the stack and Chenssy in the heap. But there is no such thing as two identical string objects in Java. So chenssy in the heap should be chenssy in the constant pool of references to strings. So the relationship between C, Chenssy and pool Chenssy should be: C –> Chenssy –> pool Chenssy.