Strings are objects in Java, so why don't we use 'new' to create them?

In addition to what was already said, String literals [ie, Strings like "abcd" but not like new String("abcd")] in Java are interned - this means that every time you refer to "abcd", you get a reference to a single String instance, rather than a new one each time. So you will have:

String a = "abcd";
String b = "abcd";

a == b; //True

but if you had

String a = new String("abcd");
String b = new String("abcd");

then it's possible to have

a == b; // False

(and in case anyone needs reminding, always use .equals() to compare Strings; == tests for physical equality).

Interning String literals is good because they are often used more than once. For example, consider the (contrived) code:

for (int i = 0; i < 10; i++) {
  System.out.println("Next iteration");
}

If we didn't have interning of Strings, "Next iteration" would need to be instantiated 10 times, whereas now it will only be instantiated once.


Strings are "special" objects in Java. The Java designers wisely decided that Strings are used so often that they needed their own syntax as well as a caching strategy. When you declare a string by saying:

String myString = "something";

myString is a reference to String object with a value of "something". If you later declare:

String myOtherString = "something";

Java is smart enough to work out that myString and myOtherString are the same and will store them in a global String table as the same object. It relies on the fact that you can't modify Strings to do this. This lowers the amount of memory required and can make comparisons faster.

If, instead, you write

String myOtherString = new String("something");

Java will create a brand new object for you, distinct from the myString object.


String a = "abc"; // 1 Object: "abc" added to pool

String b = "abc"; // 0 Object: because it is already in the pool

String c = new String("abc"); // 1 Object

String d = new String("def"); // 1 Object + "def" is added to the Pool

String e = d.intern(); // (e==d) is "false" because e refers to the String in pool

String f = e.intern(); // (f==e) is "true" 

//Total Objects: 4 ("abc", c, d, "def").

Hope this clears a few doubts. :)