For many, the Java String Pool remains a slight mystery. In this tutorial, you will take a deeper dive into understanding how the String pool works and when Java uses the String pool versus creating a separate object.
Java strings are often a point of confusion for new students. In Java, String
types are actually objects, however, they get created in a similar fashion to primitive variables such as integers, doubles, and characters.
Recall that unlike primitives, objects are created in the heap and the variable holds a reference to that heap object.
Strings, like other objects cannot be compared reliably using ==
. With objects, the ==
compares the reference value, not the actual object value. While the ==
will sometimes return true when comparing two strings, there are situations when the String
values are the same but ==
will return false.
Why is this? The answer in what you are comparing. ==
compares the reference values, so if two variables reference different objects, they will not be equal using ==
. Before getting into how the String pool works, let’s first take a look at which values actually return true using ==
versus which return true when using .equals()
. Explore the example below. When looking at the example, you will notice that there are two ways to create a new String
. The first way is using a String
literal without the constructor. The second way is to create a String
object using the String
constructor.
Did you notice that the two String
literals were equal regardless of how they were compared, but when comparing the String
literal to the String
object, only the .equals()
returned true? The answer lies in how Java uses the String Pool.
The Java String Pool is a special part of memory that is set aside to hold String
literals. When a String
literal is created, Java looks to the String Pool to see if that literal already exists. If it does, Java uses the existing String Pool object and assigns the variable the same reference. If it does not already exist, java creates a new value in the String pool, which is a process called interning.
This is why you see the two String
literals returning true when comparing using ==
. Since they have the same reference, ==
returns true.
But why does the String
object not use the same reference? The String Pool only holds true for String
literals and when the String
constructor is used, a String
object is created in the main part of the heap, not in the String Pool. So even though the Strings are the same, a String
object will never have the same reference as a String
literal.
The example below helps to illustrate this by using the identityHashCode()
command. This command returns a hash value that represents the object. If two variables point to the same object, identityHashCode
will produce the same hash value.
As you look at the output below, notice which values share the same reference. String
literals that are the same will have the same hash values, but each String
object will have a different value. None of the String
objects will ever match a value of the String
literal since they are not part of the String Pool.
To summarize, anytime a String
literal is created, Java checks the String Pool. If that literal exists, it will use that object and the new variable will have the same reference as all other variables that are assigned the same String
literal. Any other String
object will be created in the heap and be a unique object. This includes String
values that are created from user input using the Scanner
class.
As mentioned above, the process for adding a value to the String Pool is known as interning. Java actually allows you to take a String
object and add it to the String Pool manually using the .intern()
command. When doing so, the original String
still exists in the heap, but a new variable can be assigned the reference value from the String Pool.
Check out this final example below where you will see a String
object created using the Scanner
class and then that value manually interned. Notice that the manually interned value will match the other String
Literal values (assuming you enter Hello at the prompt).