|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 10
public static void main (String [] args)
{
String s = "abc";
System.out.println (s); // Output: abc
}
When the compiler compiles the preceding fragment, it stores the abc string literal in a special area of the class file—the constant pool, which is a collection of string literals, integer literals,
and other constants. The compiler also generates a byte code instruction (ldc—load constant) that pushes a reference to a String object containing abc onto the calling thread's stack, and generates another instruction (astore_1) that pops that reference from the stack and stores it in the s local variable, which corresponds to local variable 1 at the JVM level.
What creates that String object and when? Neither the Java Language Specification nor the Java Virtual Machine Specification offer answers that I
can find. Instead, I speculate the following: When a classloader—a concept I'll discuss in a future article—loads a class
file, it scans its constant pool's memory copy. For each string literal in that pool, the classloader creates a String, populates that object with the string literal's characters, and modifies the string literal's entry in the constant pool's
memory copy so ldc pushes the String's reference onto the calling thread's stack.
Because the compiler and classloader treat string literals as String objects, "abc".length() and synchronized ("sync object") are legal. "abc".length() returns the length of the String containing abc; and synchronized ("sync object") grabs the lock associated with the String containing sync object. Java regards these and other string literals as String objects to serve as a convenience for developers. As with the simplified assignment shortcut, substituting string literals
for String object reference variables reduces the amount of code you must write.
Java also offers a variety of String constructors for creating String objects. I detail three below:
public String(char [] value) creates a new String object that contains a copy of all characters found in the value array parameter. If value is null, this constructor throws a NullPointerException object.
public String(char [] value, int offset, int count) creates a new String that contains a portion of those characters found in value. Copying begins at the offset array index and continues for count characters. If value is null, this constructor throws a NullPointerException object. If either offset or count contain values that lead to invalid array indexes, this constructor throws an IndexOutOfBoundsException object.
public String(String original) creates a new String that contains the same characters as the original-referenced String.
The following code demonstrates the first two constructors:
char [] trueFalse = { 't', 'f', 'T', 'F' };
String s1 = new String (trueFalse);
String s2 = new String (trueFalse, 2, 2);
After this fragment executes, s1 references a String containing tfTF, and s2 references a String containing TF.
The following code demonstrates the third constructor: