String Interning in Java with Examples

String interning is a method of storing only one copy of each distinct string value, and then reusing them.

The distinct values are stored in a fixed-size hashtable usually referred to as string intern pool or string pool. 

The single copy of each string is called its 'intern'.

Strings in Java are immutable and hence this sharing is perfectly safe and give you better performance.

 

The String Pool

A table of strings, initially empty, is maintained by the class String.

When strings are interned, if the pool already contains a string equal to this String object's literal as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. 

 

Automatic String interning

All literal strings and compile-time string-valued constant expressions are automatically interned (using the intern() method) in Java.

This means that, any two constant expressions of type String that designate the same character sequence are represented by identical object references.

Example: Two compile-time constant expressions

String var1= "length: 10";

String var2 = "length: 10";

System.out.println("first and second are equal: " + (var1 == var2));

System.out.println("first and second are equal(with equals): " + (var1.equals(var2)));

The above statements will produce the output of:

first and second are equal: true

first and second are equal(with equals): true

  • Here, both strings are initialized with compile time constant expressions ("length: 10") and hence they will be referring to same object through automatic interning.

 

Example: Non compile-time constant, but same value

String var1 = "length: 10";

String var2 = "length: " + var1.length();

System.out.println("first and second are equal: " + (var1 == var2));

System.out.println("first and second are equal(with equals): " + (var1.equals(var2)));

This println statements will produce the output of:

first and second are equal: false

first and second are equal(with equals): true

  • Here, at runtime, both var1 and var2 will have the value of "length: 10".

  • However, var1 is initialized by a constant expression, but not var2 and hence automatic interning will not happen for var2, and hence var1 and var2 will be two different objects with same value:

  • '==' will print false and equals() will print true. 

 

Explicit string interning

We can do explicit string interning using the intern() method.

When the intern() method is invoked, if the pool already contains a string equal to this String object's literal as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. 

For any two strings s and t, s.intern() == t.intern() is true, if and only if s.equals(t) is true.

Example: Intern method

String var1 = "length: 10";

String var2 = "length: " + var1.length();

var2 = var2.intern();

System.out.println("first and second are equal: " + (var1 == var2));

System.out.println("first and second are equal(with equals): " + (var1.equals(var2)));

This will print:

first and second are equal: true

first and second are equal(with equals): true

  • Here, var1 is initialized by a constant expression, but not var2 and hence interning will not happen for var2 by default.

  • The statement var2.intern() will compare the value of var2 with values in the pool and return the reference to the string literal pointed by var1 from the pool (but doesn't change var2 itself as Strings are immutable).

  • Therefore, we needed to assign the returned intern string exlpicitely to var2, making the old String object referred to by var2 eligible for garbage colection.    

 

Example: String interning, but strings are immutable

String var1 = "length: 10";

String var2 = "length: " + var1.length();

var2.intern();

System.out.println("first and second are equal: " + (var1 == var2));

System.out.println("first and second are equal(with equals): " + (var1.equals(var2)));

This will print:

first and second are equal: false

first and second are equal(with equals): true

  • Here, var1 is initialized by a constant expression, but not var2 and hence interning will not happen for var2 by default.

  • The statement var2.intern() will compare the value of var2 with values in the pool and return the reference to the string literal pointed by var1 from the pool (but doesn't change var2 itself as Strings are immutable).

  • To change var2, we needed to assign the returned inter string exlpicitely to var2.  

 

New keyword and interning

If we create two Strings using the same literal (first example), then both of them will refer to the same String object through interning.

If we use new keyword for String creation, java will create a new String object as the JVM is obliged to create a new String object at run-time for the new keyword, rather than using the one from the String table.

String var1= "length: 10";

String var2 = new String("length: 10");

System.out.println("first and second are equal: " + (var1== var2));

This will print:

first and second are equal: false

As we have seen, you can make the second Stirng also point to the same String object referred by String one by manually calling intern() as: 

var2= var2.intern();

At this point the String object created at run-time using new keyword becomes eligible for garbage collection.

 

String interning and performance tuning

For further advanced reading on String interning details, and tuning String interning for better performance, refer to string-interning-and-performance-tuning-in-java

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) ArrayLists (1) Arrays (2) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (53) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (8) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (12) Java Programmer 2 (8) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) resources (1) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)