Creating and Initializing Strings

Immutability

The String class implements immutable character strings, which are read-only once the string has been created and initialized. Objects of the String class are thus thread-safe, as the state of a String object cannot be corrupted through concurrent access by multiple threads. Operations on a String object that modify the characters return a new String object. The StringBuilder class implements mutable strings (p. 464).

String Internment

The easiest way to create a String object is to use a string literal:

Click here to view code image

String str1 = “You cannot change me!”;

A string literal is a reference to a String object. The value in the String object is the character sequence that is enclosed in the double quotes of the string literal. Since a string literal is a reference, it can be manipulated like any other String reference. The reference value of a string literal can be assigned to another String reference: The reference str1 will denote the String object with the value “You cannot change me!” after the preceding assignment. A string literal can be used to invoke methods on its String object:

Click here to view code image

int strLength = “You cannot change me!”.length(); // 21

The compiler optimizes handling of string literals (and compile-time constant expressions that evaluate to strings): Only one String object is shared by all string-valued constant expressions with the same character sequence. Such strings are said to be interned, meaning that they share a unique String object if they have the same character sequence. The String class maintains a private string pool where such strings are interned.

Click here to view code image

String str2 = “You cannot change me!”;      // Interned string assigned.

Both String references str1 and str2 denote the same interned String object initialized with the character string: “You cannot change me!”. So does the reference str3 in the following code. The compile-time evaluation of the constant expression involving the two string literals results in a string that is already interned:

Click here to view code image

String str3 = “You cannot” + ” change me!”; // Compile-time constant expression

In the following code, both the references can1 and can2 denote the same interned String object, which contains the string “7Up”:

Click here to view code image

String can1 = 7 + “Up”;       // Value of compile-time constant expression: “7Up”
String can2 = “7Up”;          // “7Up”
boolean r = can1 == can2;     // true

However, in the following code, the reference can4 denotes a new String object that will have the value “7Up” at runtime:

Click here to view code image

String word = “Up”;
String can4 = 7 + word;  // Not a compile-time constant expression.

The sharing of String objects between string-valued constant expressions poses no problem, since the String objects are immutable. Any operation performed on one String reference will never have any effect on the usage of other references denoting the same object. The String class is also declared as final so that no subclass can override this behavior. Internally using both compact strings and string internment optimizes memory allocation and performance for strings, which is fully transparent for programmers.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *