Character strings are an inevitable part of just about any programming task. We use them for printing messages to the user, for referring to files on disk or other external media, and for people’s names, addresses, and affiliations. The uses of strings are many, almost without number (actually, if you need numbers, we’ll get to them in Chapter 5).
If you’re coming from a programming language like C,
you’ll need to remember that
String
is a defined
type (class) in Java. That is, a string is an
object, and therefore has methods. It is
not an array of characters and should not be thought of as an array.
Operations like fileName.endsWith(".gif")
and
extension.equals(".gif")
(and the equivalent
".gif".equals(extension)
) are commonplace.
Notice that a given String
object, once
constructed, is immutable. That is, once I have said String s = "Hello" + yourName;
then the particular object that
reference variable s
refers to can never be
changed. You can assign s
to refer to a different
string, even one derived from the original, as in s = s.trim( )
. And you can retrieve characters from the
original string using charAt( )
, but it isn’t called
getCharAt( )
because there is not, and never will
be, a setCharAt( )
method. Even methods like
toUpperCase( )
don’t change the
String
; they return a new
String
object containing the translated
characters. If you need to change characters within a
String
, you should instead create a
StringBuffer
(possibly initialized to the starting
value of the String
), manipulate the
StringBuffer
to your heart’s content, and
then convert that to String
at the end, using the
ubiquitous toString( )
method.
How can I be so sure they won’t add a setCharAt( )
method in the next release? Because the
immutability of
strings is one of the fundamentals of the
Java Virtual Machine. Remember that Java is
the one language that takes
multiprocessing
(threads) seriously. And takes security seriously. Got that in mind?
Good. Now think about
applets, which are prevented from
accessing many local resources. Consider the following scenario:
Thread A starts up another Thread B. Thread A creates a string called
s
containing a filename, saves a reference
s2
to it, and passes s
to some
method that requires permission. This method will certainly call the
Java Virtual Machine’s SecurityManager
[11] object, if one is installed (as it certainly will be in
an applet environment). Then, in the nanoseconds between the time the
SecurityManager
passes its approval on the named
file and the time the I/O system actually gets around to opening the
file, Thread B changes the string referred to by
s2
, to refer to a system file. Poof! If you could
do this, the entire notion of Java security would be a joke. But of
course, they thought of that, so you can’t. While you can, at
any time, assign a new String
reference to
s
, this never has any effect on the string that
s
used to refer to. Except, of course, if
s
were the only reference to that
String
, it is now eligible for garbage
collection -- it may go up the pipe!
Remember also that the
String
is a very
fundamental type in Java. Unlike most of the other classes in the
core API, the behavior of strings is not changeable; the class is
marked final
so it cannot be
subclassed. So you can’t
declare your own String
subclass. Think if you
could -- you could masquerade as a String
, but
provide a setCharAt( )
method! Again, they thought
of that. If you don’t believe me, try it out:
/** * If this class could be compiled, Java security would be a myth. */ public class WolfInStringsClothing extends java.lang.String { public void setCharAt(int index, char newChar) { // The implementation of this method // is left as an exercise for the reader. // Hint: compile this code exactly as-is before bothering! } }
Got it? They thought of that!
Of course you do need to be able to modify
strings.
There are methods that extract part of a String
;
these are covered in the first few recipes in this chapter. And there
is StringBuffer
, an important class that deals in
characters and strings and has many methods for changing the
contents, including, of course, a toString( )
method. Reformed C programmers should
note that Java strings are not arrays of chars as in C, so you must
use methods for such operations as processing a string one character
at a time; see Section 3.5. Figure 3-1 shows an overview of
String
, StringBuffer
, and
C-language strings.
While we haven’t discussed the details of the
java.io
package yet (we will, in Chapter 9), you need to be able to
read text
files for some of these programs. Even if you’re not familiar
with java.io
, you can probably see from the
examples that read text files that a
BufferedReader
allows you to read “chunks”
of data, and that this class has a very convenient readLine( )
method.
We won’t show you how to sort an array of strings here; the more general notion of sorting a collection of objects is discussed in Section 7.9.
[11]
SecurityManager
is a
class that is consulted on whether the current application is allowed
to do certain things, such as open local disk files, open arbitrary
network connections, etc. Applets run with a more restrictive
security manager than do normal applications, for example.
18.118.139.224