In the previous section, we explained that strings are essentially character arrays. At the same time, we explained in detail the areas where strings must be judged to be equal. In this section, we will delve into the characteristics of strings. Let ’s take a look.


We still explore the immutability of strings with the help of initialization strings, as follows:

String str = "Jeffcky" ;
System.out.println (str);


In the above, we create a string literally. Next, we perform the following operations on the string str:

String str = "Jeffcky" ;
str.substring (0,3) .concat ("wang"). toLowerCase (). trim (); System.out.println (str);


We see that after the string string is intercepted, concatenated, and lowercase, the value of the string has not changed. This is the immutability of the string. We can check any method for manipulating the string, such as the concat method source code. :



public String concat (String str) {
         int otherLen = str.length ();
         if (otherLen == 0 ) {
             return  this ;
        int len = value.length;
         char buf [] = Arrays.copyOf (value, len + otherLen);
        str.getChars (buf, len);
        return  new String (buf, true );



Looking at the source code of concat, we can see that the original str value has never changed, its value is just copied, then the text we connected is added to the copied copy, and finally a new String is returned. So here we know that the operations on strings are to copy a string, then operate on the copied string, and finally return a new String object.

String pool

Let’s take a look at the code example given in the previous section, as follows:



public  class Main {
     public  static  void main (String [] args) {
        String str1 = "Jeffcky" ;
        String str2 = "Jeffcky" ;
        System.out.println (str1 == str2);
        System.out.println (str1.equals (str2));




When we instantiate a String (in this case Jeffcky) it is held in Java heap memory (for dynamic memory allocation of all Java objects). Although we have two different reference variables in this example, they both refer to the same memory location in Java Heap Memory. Although it looks like there are two different String objects, there is actually only one, and str2 will never It is instantiated as an object, but instead allocates an object corresponding to str1 in memory. This is because Java optimizes strings. Every time you want to instantiate such a String object, the value to be added to the heap memory and The previously added values ​​are compared. If the value already exists, the object is not initialized and the value is assigned to a reference variable. These values ​​are stored in a string named “string pool” which contains all literal string values, of course We can bypass this situation with the new operator.

Why are strings immutable or final?

We have described the immutability of strings through examples, so why are strings immutable?
“. I think it’s mainly about sharing objects efficiently and saving memory space. When the program runs, the number of String instances created will also increase. If the String constants are not cached, there will be a large number of Strings in the heap space, which will occupy memory space. Therefore, String objects are cached in the string pool after creation. The string is shared by multiple clients. At this time, the modification of the string by one client affects other clients. Therefore, this risk is avoided by the immutability of the string. At the same time, the cache and shared string constants are used. The JVM is Java applications save memory.

With string immutability, it can be safely shared by multiple threads, we do not have to worry about thread synchronization, and ensure thread safety.

With the immutability of strings, you can use HashMap very well. We can correctly retrieve the objects stored in the HashMap. If the string is variable and is inserted into the HashMap and the string content is modified, it will appear at this time. The object to which the corresponding string is mapped is missing.

With string immutability, the string hash code is cached at this time, so no calculation is required each time the string’s hashcode method is called, making it very fast to use keys in a HashMap.

Others, etc …

Let’s take a look at the implementation of String through source code, as follows:



public  class Main {
     public  static  void main (String [] args) {
         char a [] = {'j', 'e', ​​'f', 'f', 'c', 'k', 'y' };
        String str = new String (a);
        System.out.println (str);



We look at the source code by creating a string from a character array, as follows:



public  final  class String
     implements, Comparable <String> , CharSequence {
     / ** The value is used for character storage. * / 
    private  final  char value [];

    / ** 
     * Initializes a newly created { @code String} object so that it represents
     * an empty character sequence. Note that use of this constructor is
     * unnecessary since Strings are immutable.
     * / 
    public String () {
         this .value = new  char [0 ];

    / ** 
     * Allocates a new { @code String} so that it represents the sequence of
     * characters currently contained in the character array argument. The
     * contents of the character array are copied; subsequent modification of
     * the character array does not affect the newly created string.
     * @param   value
     * The initial value of the string
     * / 
    public String ( char value []) {
         this .value = Arrays.copyOf (value, value.length);



We see that the string object is defined as final (we haven’t learned final yet, we just need to know that the class is not inheritable through the final keyword modification), there are many examples on the Internet that string objects are modified by the final keyword, indicating characters Strings are immutable. In fact, this statement is not rigorous and wrong. The reason why String is decorated with the final keyword is to ensure that the immutability of the String class cannot be destroyed through expansion and overriding behavior rather than stating that the string is immutable. For example, the following example:



public  class Main {
     public  static  void main (String [] args) {
        String str1 = "Jeffcky" ;
        String str2 = "Jeffcky" .toUpperCase ();
        System.out.println (str1);
        System.out.println (str2);




Now the string str2 is “Jeffcky” .toUpperCase (), we will change the same object to “JEFFCKY”. If the string variable is modified, other string variables will also be automatically affected. For example, str1 will be “JEFFCKY” Obviously not desirable.


In this article, we introduced the immutability of the string, the string pool feature in detail, and explained why the string is immutable, and explained that the definition of the string class as final does not mean that it is immutable, but it is not allowed to be extended or overwritten. Destroy the immutability of the string.


Java entry series [1] string creation method

Java entry series [2] string features

Java entry series [3] stringbuilder string buffer

Java entry series [4] packaging class

Java entry series [5] inheritance abstract classes interfaceson

Java entry series [6] Principles of dynamic array

Java entry series [7] collection arraylist

Java entry series [8] principles of doubley linked list alogrithm

Java entry series [9] linkedlist source code analysis

Java entry series [10] Hash algorithm principle

Java entry series [11] Hashtable source code analysis

Java entry series [12] Hashcode and equals

Java entry series [13] Principles of the read-black tree algorithmn method

Java entry series [14] Hashmap source code ananlysis


Orignal link: