In this section, we will learn what the String Pool is and how it works in Java.
Prerequisite: String literals.
What is String Pool in Java?
The string pool is basically a part of the heap memory where the JVM stores string literals.
The string pool brings efficiency, as you’ll soon see how.
When we create a string literal, behind the scene the compiler will create an object of type String and stores the value of the string literal in that object. This object is stored in the string pool. Also, if there’s a variable that wants to store the string literal, it will store the reference of the object that was created by the compiler and not the string itself.
Example: storing String values in Java String pool
public class Simple { public static void main(String[] args) { String st1 = "John"; String st2 = "Doe"; String st3 = "John"; } }
Here’s how compilers treat string literals:
When a compiler sees a string literal just like those in the example above, it will first check the string pool to see if there’s an object that stored the same value.
For example, when the compiler reaches to the “John” which is a string literal, it will check the string pool to see if there’s an object that stored this value.
Let’s say there isn’t. In such case, the compiler will create a new object of type String and stores this value in it. Finally, it will store this newly created object in the string pool and returns a reference to the object and stores that in the st1 variable.
So the st1 variable has the memory address of the object that stored the value “John” and not the object itself.
Next, the compiler sees the “Doe” string literal. Again, it will check the string pool for an object that has the value of “Doe”. Because there’s no object with such value, it will create a new one and stores the reference of this object in the st2 variable.
Finally, the compiler reaches to the third string literal, which is “John”. The compiler checks the string pool for an object that has this value and this time it sees one object (The one that was created for the first string literal).
So now instead of creating a new object for this third string literal, it will use the one that already exists and returns the memory address of that object. This memory address will be stored in the st3 variable.
Now the st1 and st3 are both pointing to the same String object.
Here’s how we can prove this:
The equal == operator is used to check whether or not the two values are equal. But for objects, this operator checks to see if both objects are in the same memory location! Basically, the equality is based on the memory address and not the content.
So if the st1 and st3 are pointing to the same memory location, then the result of the comparison between the two variables should result true.
Example:
public class Simple { public static void main(String[] args) { String st1 = "John"; String st2 = "Doe"; String st3 = "John"; if (st1 == st3){ System.out.println("The two variables are pointing to the same object"); } } }
Output: The two variables are pointing to the same object.
As you can see, these two variables have the same memory address.
You might still not be convinced, so here’s another example: As mentioned in the String section, when we create an object of type String but via the new keyword, it will be stored in the heap memory (not the string pool area). So even if the content of that String is the same as the last object, still there will be two independent objects that only their values were the same.
public class Simple { public static void main(String[] args) { String st1 = new String("John"); String st2 = "Doe"; String st3 = "John"; if (st1 == st3){ System.out.println("The two variables are pointing to the same object"); }else{ System.out.println("No, these are two different objects"); } } }
Output: No, these are two different objects
As you can see, this time the values of the st1 and st3 variables are not the same (each one is pointing to another object) so the result of the if statement is false and the body of the else block ran.
Again, for string literals, if two values are the same, there will be only one object created for both of the string literals.
But if there are two objects that are created via the new keyword, there will be two independent objects but with the same values.
Example:
public class Simple { public static void main(String[] args) { String st1 = new String("John"); String st3 = new String("John"); if (st1 == st3){ System.out.println("The two variables are pointing to the same object"); }else{ System.out.println("No, these are two different objects"); } } }
Output: No, these are two different objects.
In String class there’s a method named intern() that can be used to save a copy of an object that is created via the new keyword into string pool.
Example:
public class Simple { public static void main(String[] args) { byte[] bytes = "Life is good".getBytes(); String st1 = new String(bytes).intern(); String st2 = "Life is good"; if (st1 == st2){ System.out.println("Yes both variables are pointing to the same object"); } } }
Output: Yes both variables are pointing to the same object
As you can see the first string object was created via the new keyword but we called the intern() method over the object and so a copy of this object was stored in the string pool and the reference of this pooled object returned.
Java String pool Notes:
Try and use string literals instead of creating string objects via the new keyword. This will increase the performance of the program because there’s no need to create objects every time the same string appears in that program. It will also help to stop wasting memory space for repeated strings in the program.