String Class Part 3 Tutorial

In this tutorial, I will introduce you to the concept of the String Literal Pool (aka String Constant Pool). The String Pool exists as a special section of the heap memory and it contains distinct instances of string literal values. In part one I stated "... that the string literal "ABC" is equivalent to new String("ABC") in the compiled code." and that is essentially correct. However, there is one subtle difference that warrants explanation. In order to increase performance and save memory, string literal instances are stored in a special section of the heap memory reserved for distinct string values (string pool). When a reference to a string literal is being created, Java first checks for a string with same value in the string literal pool, if one does exist it just returns that reference, otherwise a new string literal instance will be created in the pool and that reference is returned.
In the statement String s = "ABC"; the "ABC" literal instance will be stored in the string pool section of heap memory.
In the statement String s = new String("ABC"); the instance with the value of "ABC" will be stored in regular good old heap memory.
Why the difference? To increase performance and save memory.
Consider the following:

for (int i = 99; i > 0; i--) {
      System.out.println( i + " bottles of beer on the wall " + i + new String(" bottles of beer. Take one down, pass it around ...") );
}

In the example above there would be just one instance of the string literal " bottles of beer on the wall " located in the string pool. However, there will be 99 instances of " of beer. Take one down, pass it around ..." on the ordinary heap because we instructed Java to do so by using the new operator.

That seems like a real waste of memory and computing time creating all those objects, is there a way to prevent a new instance from being created every time? Yes, a concept called string interning will allow us to do just that. The String class has a method called intern() that will force creation of a new string instance into the string constant pool. The intern method works like this, first it checks for a string with same value in the string literal pool, if one does exist it just returns that reference, otherwise a new string literal instance will be created in the pool and that reference is returned.

We are almost ready to run some code, just one more important thing to go over. Every object inherits the equals() method from the Object class. The equals() method in the string class compares the actual instance object string values. When two string reference variables are compared, == compares if they refer to the same object.
String a = "ABC";
String b = new String("ABC");
( a.equals(b) ); true
// "ABC" equals "ABC"
( a == b ); false // a refers to an instance on the string pool and b refers to an instance in the regular heap.



Open the command prompt (CMD - see the Getting Started ) and type in the following commands.

C:\Windows\System32>cd \
C:\>md Java
C:\>cd Java
C:\Java>
C:\Java>md StringThree
C:\Java>cd StringThree
C:\Java\StringThree>Notepad StringThree.java

Copy and Paste, or type the following code into Notepad and be sure to save the file when you are done.


class StringThree {
    public static void main(String args[]) {
        for (int i = 99; i > 0; i--) {
      	        System.out.println( i + " bottles of beer on the wall " + i + new String(" bottles of beer. Take one down, pass it around ...") );
        } 
        System.out.println("\n-------");
        String s1 = "TEST";	
        String s2 = "TEST";
        String s3 = new String("TEST");
        String s4 = new String("TEST");
        String s5 = new String("TEST").intern();

        System.out.println("s1 == s2 " + (s1 == s2) );
        System.out.println("s3 == s1 " + (s3 == s1) );
        System.out.println("s3 == s4 " + (s3 == s4) );
        System.out.println("s5 == s1 " + (s5 == s1) );
        System.out.println("s5 == s2 " + (s5 == s2) );

    }
}

Now switch back to the command prompt (CMD) and type in javac StringThree.java and press Enter.
Now type in java StringThree and press Enter.


C:\Java\StringThree>javac StringThree.java
C:\Java\StringThree>java StringThree
99 bottles of beer on the wall 99 of beer. Take one down, pass it around ...
...

-------
s1 == s2 true
s3 == s1 false
s3 == s4 false
s5 == s1 true
s5 == s1 true
    

Final thoughts

To recap, string literals are stored as instances in the string literal pool. Strings objects created using the new operator are stored in regular heap memory, unless you invoke the intern() method which will force them to the string literal pool.


Tutorials