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:
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:
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.
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:
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”:
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:
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.
Leave a Reply