Strings in Java

Strings in Java are immutable. Which means when you have assigned a String a value, the value can never change– it’s immutable. Let us check this out with an example
String a=”Java “;
a=a.concat(“Rules”);

The VM took the value of String a (“Java “) and tacked “Rules” onto the end, giving the value “Java Rules”. Since Strings are immutable, the VM could not stuff this new String “Rules” into the original String “Java ” which is referenced by a. So it creates a new String object, gives it the value “Java Rules” and made a refer to it. Since a String is an object in Java, logically we have three String objects stored in the memory (“Java “,”Rules” and “Java Rules”) and only one String reference a pointing to “Java Rules”. So the other two strings even though exist in the memory are considered “lost” to the program. No code
in the program has reference to reach the “lost” strings.

String Constant Pool
String a=”Java “;
a=a.concat(“Rules”);
String b=”Java Features “;
b=b.concat(“Rock”);

In the above example logically there are six String objects(“Java “,”Rules”,”Java Features “,”Rock”,”Java Rules” and “Java Features Rock”) and of which only two of them are reachable through the reference variables a and b. So the other four objects are lost and just lying in the memory. So in such a case where there is a lot of string manipulation taking place, lot of String literals are created and there is a lot of redundancy within the universe of String literals for a program. To make Java memory more efficient, JVM puts aside a special area of memory called the “String constant pool”. If the compiler encounters a String literal in a program, it would check to see if a similar String exists in the String constant pool. If it finds a match then the reference is directed to the existing literal in the memory and no new String literal object is created.
For example-
String c=”Java “; in this case the reference c is directed to the String literal object “Java ” present in the String constant pool, since we already created it previously.
Comparing Strings (== vs equals)
String a=”Java”;
String b=”Java”;
if(a==b)
System.out.println(“a and b are equal”);
if(a.equals(b))
System.out.println(“a and b are equal”);
output-
a and b are equal
a and b are equal

“==” returns true if both the references points to the same object in the reference and since String class overrides the “equal” method of the Object class, it returns true if the contents of both the objects stored in these references are same. As per the String constant pool concept you can say that both references a and b point to the same String literal object “Java” that is stored in the String constant pool.
“==” Gotcha
String a=”Java Rules”;
String b=”Java “;
String c=b+”Rules”;
if(a==c)
System.out.println(“a and b are equal”);
else
System.out.println(“a and b are not equal”);
output-
a and b are not equal

According to the Java Language Specification(JLS) “If only one operand expression is of type String, then string conversion is performed on the other operand to produce a string at run time. The result is a reference to a String object (newly created, unless the expression is a compile-time constant expression)that is the concatenation of the two operand strings”. So Strings computed by constant expressions are computed at compile time and then treated as if they were literals. But Strings computed at run time are newly created and therefore distinct. So String c is computed at run time and is different from the String a since the expression “String c=b+”Rules”;” is not a constant expression.