Wednesday, June 27, 2007

Comparisons of C++ and Java (V): Immutability of Strings

Strings are not the same in C++ and Java regarding to immutability. In Java, String objects are immutable, where C++ string type is mutable.

Let’s take a look at some examples:

A C++ Example

string str1=”It is Friday, ”;
string str2=”I am completely released”;
str1.append(str2);

cout<<str1<<endl;

The program will print: It is Friday, I am completely released

A Java Example

String str1 = “It is Friday,”;
String str2 = “I am completely released!”;
str1.concat(str2);

System.out.println(str1);

The program will print: It is Friday,

Immutability of strings in C++ and Java

In C++, a string type is mutable. As shown in example 1, str1.append(str2) appends str2 to the end of str1, and str1 becomes “It is Friday, I am completely released”. In addition to append(), similar functions like substr() and assign() etc. in std::string class DO alter a C++ string.

By contrast, in Java, String objects designed as immutable. As shown in example 2, str1.concat() creates a new String object, the old string str1 remains unchanged. It is also true for some other methods such as substring(), toLowerCase() and toUpperCase(). In other words, any operation performed on one String reference will never have any effect on the content of the String object.

Reduce Object Creation in Java

Because of its mutability and the object-creation overhead of a String object, performance could be a problem. In fact, Java provides several mechanisms to reduce String objects creation:

  • String literal Pool: Java compiler optimizes handling of String literals. Only one String object is shared be all strings that have same character sequence. Such strings are said to be interned, meaning that they share a unique String object. The String class maintains a private pool called String intern pool, where such strings are interned. Java automatically interns String literals.
  • Interning of Strings: we can also explicitly make a String object interned. Intern() method from String class can help achieve interning of a String . When the intern() method is invoked on a String, JVM first checks the String literal pool. If a String with the same content is already in the pool, a reference to the String in the pool is returned. Otherwise, the String is added to the pool and a reference to it is returned. The result is that after interning, all Strings with the same content will point to the same object.
Can we intern all Strings? The answer is may not. As the intern string pool grows large, the cost to find a String in the pool could become more expensive than creating a new object.
  • StringBuffer and StringBuilder serves as mutable strings: as a sort of complementary, Java provides StringBuffer as a sort of mutable string. Content of a StringBuffer object can be modified. It is more efficient to use a StringBuffer instead of operations that result in the creation of many intermediate String object. Introduced in J2SE 5.0, Stringbuilder class provides an API compatible with StringBuilder but is unsynchronized.