String is a class, so it is not a base type, but it has built-in language support, eg to use + as the concatenation operator.
Strings are immutable: once created they can never be changed. If you concatenate a String to another one you are not modifying either of those objects but creating a brand new one. If there are then no longer any references to the original strings they may be cleared away by the garbage collector. So operations on Strings, which often create new ones, are not very efficient and can cause fragmentation of the heap - remember that.
As we have seen, but not explicitly stated, strings can be declared and assigned literally by giving values in double quotes, and then manipulated:
String s = "Java 6 Standard Edition";
// Doesn't need new: assigning a literal String creates the object
String t = s.substring (0, 6); // beginIndex, endIndex
String u = s.toUpperCase ();
See the API documentation for all the methods available. Some of the most useful ones follow here.
int length (); // NB: Method, in contrast to array.length field
char charAt (int index);
int indexOf (String str, int fromIndex);
int lastIndexOf (String str);
String substring (int beginIndex, int endIndex);
String toLowerCase ();
String toUpperCase ();
String trim ();// Deletes whitespace from both ends
These all either extract something from a string or create new strings, they cannot amend the (immutable) string.
It is important to remember that there is a difference between an empty String and a null String:
String s1 = ""; // Empty but object exists
String s2; // Null - no object yet
String s3 = null; // Ditto but more explicit.
The reason that strings are immutable is so that when the JVM meets a literal string declaration that is the same as an earlier one it can use the same string that it put in memory before. This happens even if the identical strings are in different classes, in different packages.
Class String does have a proper version of method equals ()
that we met a few pages back.
Because of immutability, literal strings can be compared by reference:
String s1 = "An example";
// ... some time later:
String s2 = "An example";
if (s1 == s2)
{
// Will be true because the JVM would have reused s1 for s2.
}
if (s1.equals (s2))
{
// Also true because the content is the same (s1 and s2 refer to the same object)
}
HOWEVER: if Strings are created by using constructors the JVM will not reuse them like that:
String s1 = new String ("An example");
// ... some time later:
String s2 = new String ("An example");
if (s1 == s2)
{
// FALSE because the JVM would NOT have reused s1 for s2.
}
if (s1.equals (s2))
{
// Still TRUE because the content is the same
}
So be careful when comparing strings: equals ()
is always safer.