Skip to main content.

Web Based Programming Tutorials

Homepage | Forum - Join the forum to discuss anything related to programming! | Programming Resources

Java Unleashed Second Edition

Chapter 12 -- The Language Package

Chapter 12

The Language Package

by Michael Morrison


CONTENTS


The Java language package is the heart of the Java language. In this chapter, you learn more about some of the classes that make up the language package (java.lang). You'll find that many of the classes in the language package are indispensable in writing Java programs.

The language package contains many classes, each with a variety of member variables and methods. You don't learn about every class and every method in this chapter (that would simply be too much material to cover in a single chapter). Rather, you focus on the most important classes in the language package; classes that come in the most useful as you begin developing your own Java classes. Please note that although the multithreading and error-handling classes are part of the language package, they aren't covered in this chapter; Chapter 9, "Threads and Multithreading" and Chapter 10, "Exception Handling," are devoted to these classes.

The Object Class

The Object class is probably the most important of all Java classes, simply because it is the superclass of all Java classes. It is important to have a solid understanding of the Object class because all the classes you develop inherit the variables and methods of Object. The Object class implements the following important methods:

The clone() Method

Object clone()

The Object clone() method creates a clone of the object it is called on. clone() creates and allocates memory for the new object being copied to. clone() actually creates a new object and then copies the contents of the calling object to the new object. An example of using the clone() method follows:

Circle circle1 = new Circle(1.0, 3.5, 4.2);
Circle circle2 = circle1.clone();

In this example, the circle1 object is created, but the circle2 object is only declared. circle2 is not created by using the new operator; it is created when circle1 calls the clone() method to create a clone of itself.

The equals() Method

boolean equals(Object obj)

The equals() method compares two objects for equality. equals() is applicable only when both objects have been stored in a hash table.

The hashCode() Method

int hashCode()

The hashCode()method returns the hashcode value for an object. Hashcodes are integers that uniquely represent objects in the Java system.

The getClass() Method

final Class getClass()

The getClass()method returns the runtime class information for an object in the form of a Class object. The Class object keeps up with runtime class information such as the name of a class and the parent superclass.

The toString() Method

String toString()

The toString() method returns a string representing the value of an object. Because the value of an object varies depending on the class type, it is assumed that each class will override the toString() method to display information specific to that class. The information returned by toString() can be very valuable for determining the internal state of an object when debugging.

Data Type Wrapper Classes

The data type wrapper classes provide object versions of the fundamental Java data types. Type wrapping is important because many Java classes and methods operate on classes rather than fundamental types. Furthermore, by creating object versions of the simple data types, it is possible to add useful member functions for each type. Following are the type wrapper classes supported by Java:

Althouger implements methods specific to each data type, a handful of methode to all the wrappers. These methods follow:

Note
Actually, the valueOf() method isn't implemented in the Character class, but it is implemented in all the other wrapper classes.

The ClassType() Method

ClassType(type)

The ClassType() method is actually the constructor for each class. The wrapper constructors take as their only parameter the type of data they are wrapping. This enables you to create a type wrapper from a fundamental type. For example, you can use the constructor for the Character class like this:

Character c1 = new Character('x');

The typeValue() Method

type typeValue()

The typeValue() method is used to get the fundamental type back from a wrapper. typeValue() returns a value of the same type as the fundamental type it wraps. Following is an example of how a fundamental type can be extracted from a wrapper object:

char c2 = c1.charValue();

Note
Remember that fundamental types are not represented in Java by classes or objects. Data type wrapper classes provide a means of representing a fundamental type as an object, which is often useful. Wrapper classes are different from other Java classes in that their only purpose is to allow fundamental types to be represented as objects. You can easily distinguish wrapper classes from primitive types because the first letter of wrapper class names is always capitalized.

The hashCode() Method

int hashCode()

The hashCode() method returns the hashcode for a type wrapper object. This hashCode() method is simply an overridden version of the hashCode() method contained in the Object class.

The toString() Method

String toString()

The toString() method is used to get a string representation of the internal state of an object. toString() is typically overridden in each class so that it reflects unique state implementations. Following is an example of how you can output the state of a wrapper variable using toString():

System.out.println(c1.toString());

The equals() Method

boolean equals(Object obj)

The equals() method is used to test for equality between two wrapper objects. This is the same equals() method that is implemented in Object and inherited by all other objects in Java.

The valueOf() Method

static boolean valueOf(String s)

The valueOf() method is implemented in all the type wrappers except Character. valueOf(), which is static, is used to convert a string to a value of a particular wrapper type. valueOf() parses the String parameter s and returns the value of it.

Now that you have an idea of what functionality all the wrapper classes share, it's time to take a look at some of the specifics of each class.

The Boolean Class

The Boolean class wraps the boolean fundamental data type. Boolean implements only one method in addition to the common wrapper methods already mentioned: getBoolean().

The getBoolean() Method

static boolean getBoolean(String name)

The getBoolean() method returns a type boolean that represents the boolean property value of the String parameter name. The name parameter refers to a property name that represents a boolean property value. Because getBoolean() is static, it is typically meant to be used without actually instantiating a Boolean object.

Note
Java properties are system variables that define the characteristics of the Java runtime environment. For example, there is a property called os.name that specifies the name of the operating system in which the Java runtime is executing. In my case, os.name is set to "Windows 95".

Member Variables

The Boolean class also includes two final static (constant) data members: TRUE and FALSE. TRUE and FALSE represent the two possible states that the Boolean class can represent. It is important to note the difference between true and false and Boolean.TRUE and Boolean.FALSE. The first pair applies to boolean fundamental types; the second pair applies to Boolean classes; they cannot be interchanged.

The Character Class

The Character class wraps the char fundamental type and provides some useful methods for manipulating characters. The methods implemented by Character, beyond the common wrapper methods, follow:

All these methods are static, which means that they can be used without instantiating a Character object.

The isLowerCase() and isUpperCase() Methods

static boolean isLowerCase(char ch)
static boolean isUpperCase(char ch)

The isLowerCase() and isUpperCase() methods return whether or not a character is an uppercase or lowercase character. An example of using the isLowerCase() method follows:

Character c = new Character('g');
boolean isLower = Character.isLowerCase(c);

In this case, the boolean variable isLower is set to true because 'g' is a lowercase character.

The isDigit() Method

static boolean isDigit(char ch)

The isDigit()method simply returns whether or not a character is a digit (0 to 9). Following is an example of how to use the isDigit() method:

boolean isDigit = Character.isDigit('7');

The boolean variable isDigit is set to true here because '7' is in fact a numeric digit.

The isSpace() Method

static boolean isSpace(char ch)

The isSpace() method returns whether or not a character is whitespace. (Whitespace is defined as any combination of the space, tab, newline, carriage return, or linefeed characters.) Following is an example of how to use isSpace():

boolean isSpace = Character.isSpace('\t');

In this example, the isSpace boolean variable is set to true because the tab ('\t') character is considered whitespace.

The toLowerCase() and toUpperCase() Methods

static char toLowerCase(char ch)
static char toUpperCase(char ch)

The toLowerCase()and toUpperCase() methods convert a character to a lowercase or uppercase character. If a character is already lowercase and toLowerCase() is called, the character is not changed. Similarly, toUpperCase() does nothing to uppercase characters. Following are a few examples of using these methods:

char c1 = Character.toUpperCase('g');
char c2 = Character.toLowerCase('M');

In the first example, c1 is converted from 'g' to 'G' with the call to the toUpperCase() method. In the second example, c2 is converted from 'M' to 'm' with the call to toLowerCase().

The digit() Method

static int digit(char ch, int radix)

The digit() method returns the numeric (integer) value of a character digit in base 10. The radix parameter specifies the base of the character digit for conversion. If the character is not a valid digit, -1 is returned. Following are a few examples of using the digit() method:

char c1 = '4';
char c2 = 'c';
int four = Character.digit(c1, 10);
int twelve = Character.digit(c2, 16);

In the first example, the character '4' is converted to the integer number 4 using the digit() method. In the second example, the hexadecimal number represented by the character 'c' is returned as the base 10 integer number 12.

The forDigit() Method

static char forDigit(int digit, int radix)

The forDigit() method performs the reverse of the digit() method: it returns the character representation of an integer digit. Once again, radix specifies the base of the integer number. Following is an example of how to use forDigit():

int i = 9;
char c = Character.forDigit(i, 10);

In this example, the integer number 9 is converted to the character '9' by the forDigit() method.

Member Variables

The Character class provides two final static data members for specifying the radix limits for conversions: MIN_RADIX and MAX_RADIX. The radix for a number is its base, such as binary, octal, or hexadecimal. These common radixes have values of 2, 8, and 16, respectively. MIN_RADIX specifies the minimum radix (base 2) for performing numeric-to-character conversions and vice-versa. Likewise, MAX_RADIX specifies the maximum radix (base 36) for conversions.

The Integer and Long Classes

The Integer and Long classes wrap the fundamental integer types int and long and provide a variety of methods for working with integer numbers. The methods implemented by Integer follow:

The parseInt() Methods

static int parseInt(String s, int radix)
static int parseInt(String s)

The parseInt() methods parse strings for an integer value and return the value as an int. The version of parseInt() with the radix parameter enables you to specify the base of the integer; the other version of parseInt() assumes a base of 10.

The longValue(), floatValue(), and doubleValue() Methods

long longValue()
float floatValue()
double doubleValue()

The longValue(), floatValue(), and doubleValue() methods return the values of an integer converted to the appropriate type. For example, the following code shows how to convert an integer to a double:

Integer i = new Integer(17);
float f = i.floatValue();

In this example, the value of the Integer variable i is converted to a float value and stored in the float variable f. The result is that the Integer value 17 is converted to the float value 17.0.

The getInteger() Methods

static Integer getInteger(String name)
static Integer getInteger(String name, int val)
static Integer getInteger(String name, Integer val)

The getInteger() methods return an integer property value specified by the String property name parameter name. Notice that all three of the getInteger() methods are static, which means that you don't have to instantiate an Integer object to use these methods. The differences between these methods is what happens if the integer property isn't found. The first version returns 0 if the property isn't found, the second version returns the int parameter val, and the last version returns the Integer object value val.

Member Variables

The Integer class also includes two final static (constant) data members: MINVALUE and MAXVALUE. MINVALUE and MAXVALUE specify the smallest and largest numbers that can be represented by an Integer object.

The Long class is similar to the Integer class except that it wraps the fundamental type long. Long actually implements similar methods as Int, with the exception that they act on long-type numbers rather than int-type numbers.

Floating-Point Classes

The Float and Double classes wrap the fundamental floating-point types float and double. These two classes provide a group of methods for working with floating-point numbers. The methods implemented by the Float class follow:

The isNaN() Methods

boolean isNaN()static boolean isNaN(float v)

The isNaN() method returns whether or not the Float value is the special not-a-number (NaN) value. The first version of isNaN() operates on the value of the calling Float object. The second version is static and takes the float to test as its parameter, v.

The isInfinite() Methods

boolean isInfinite()
static boolean isInfinite(float v)

The isInfinite() method returns whether or not the Float value is infinite, which is represented by the special NEGATIVE_INFINITY and POSITIVE_INFINITY final static member variables. Like the isNaN() method, isInfinite() comes in two versions: a class value version and a static version that takes a float as an argument.

The intValue(), longValue(), and doubleValue() Methods

int intValue()
long longValue()
double doubleValue()

The intValue(), longValue(), and doubleValue() methods return the values of a floating-point number converted to the appropriate type. For example, the following code shows how to convert a Float to a long:

Float f = new Float(5.237);
long l = f.longValue();

In this example, the value of the Float variable f is converted to a long and stored in the long variable l. This action results in the floating-point value 5.237 being converted to the long value 5.

The floatToIntBits() and intBitsToFloat() Methods

static int floatToIntBits(float value)
static float intBitsToFloat(int bits)

The last two methods implemented by the Float class are floatToIntBits() and intBitsToFloat(). The floatToIntBits() and intBitsToFloat() methods convert floating-point values to their integer bit representations and back.

Member Variables

The Float class also has a group of final static (constant) data members: MINVALUE, MAXVALUE, NEGATIVE_INFINITY, POSITIVE_INFINITY, and NaN. MINVALUE and MAXVALUE specify the smallest and largest numbers that can be represented by a Float object. NEGATIVE_INFINITY and POSITIVE_INFINITY represent negative and positive infinity, while NaN represents the special
not-a-number condition.

The Double class is very similar to the Float class. The only difference is that Double wraps the fundamental type double instead of float. Double implements similar methods as Float, with the exception that the methods act on double rather than float-type numbers.

The Math Class

The Math class contains many invaluable mathematical functions along with a few useful constants. The Math class isn't intended to be instantiated; it is basically just a holding class for mathematical functions. Additionally, the Math class is declared as final-you can't derive from it. The most useful methods implemented by the Math class follow:

Trigonometric Methods

static double sin(double a)
static double cos(double a)
static double tan(double a)
static double asin(double a)
static double acos(double a)
static double atan(double a)

The trigonometric methods sin(), cos(), tan(), asin(), acos(), and atan() perform the standard trigonometric functions on double values. All the angles used in the trigonometric functions are specified in radians. Following is an example of calculating the sine of an angle:

double dSine = Math.sin(Math.PI / 2);

Notice in the example that the PI constant member of the Math class was used in the call to the sin() method. You learn about the PI constant member variable of Math at the end of this section.

The exp(), log(), sqrt(), and pow() Methods

static double exp(double a)
static double log(double a)
static double sqrt(double a)
static double pow(double a, double b)

The exp() method returns the exponential number E raised to the power of the double parameter a. Similarly, the log() method returns the natural logarithm (base E) of the number passed in the parameter a. The sqrt() method returns the square root of the parameter number a. The pow() method returns the result of raising a number to a power. pow() returns a raised to the power of b. Following are some examples of using these Math methods:

double d1 = 12.3;
double d2 = Math.exp(d1);
double d3 = Math.log(d1);
double d4 = Math.sqrt(d1);
double d5 = Math.pow(d1, 3.0);

The ceil(), floor(), round(), and rint() Methods

static double ceil(double a)
static double floor(double a)
static int round(float a)
static long round(double a)
static double rint(double a)

The ceil() and floor() methods return the "ceiling" and "floor" for the passed parameter a. The ceiling is the smallest whole number greater than or equal to a; the floor is the largest whole number less than or equal to a. The round() methods round float and double numbers to the nearest integer value, which is returned as type int or long. Both round() methods work by adding 0.5 to the number and then returning the largest integer that is less than or equal to the number. The rint() method returns an integral value, similar to round(), that remains a type double. Following are some examples of using these methods:

double d1 = 37.125;
double d2 = Math.ceil(d1);
double d3 = Math.floor(d1);
int i = Math.round((float)d1);
long l = Math.round(d1);
double d4 = Math.rint(d1);

Notice in the first example of using round() that the double value d1 must be explicitly cast to a float. This is necessary because this version of round() takes a float and returns an int.

The atan2() Method

static double atan2(double a, double b)

The atan2() method converts rectangular coordinates to polar coordinates. The double parameters a and b represent the rectangular x and y coordinates to be converted to polar coordinates, which are returned together as a single double value.

The random() Method

static synchronized double random()

The random() method generates a pseudo-random number between 0.0 and 1.0. random() is useful for generating random floating-point numbers. To generate random numbers of different types, you should use the Random class, which is located in the utilities package, java.util. The utilities package, including the Random class, is covered in the next chapter.

The abs() Methods

static int abs(int a)
static long abs(long a)
static float abs(float a)
static double abs(double a)

The abs() methods return the absolute value of numbers of varying types. There are versions of abs() for the following types: int, long, float, and double. Following is an example of using the abs() method to find the absolute value of an integer number:

int i = -5, j;
j = Math.abs(i);

The min() and max() Methods

static int min(int a, int b)
static long min(long a, long b)
static float min(float a, float b)
static double min(double a, double b)
static int max(int a, int b)
static long max(long a, long b)
static float max(float a, float b)
static double max(double a, double b)

The min()and max()methods return the minimum and maximum numbers given a pair of numbers to compare. Like the abs() methods, the min() and max() methods come in different versions for handling the types int, long, float, and double. Following are some examples of using the min() and max() methods:

double d1 = 14.2, d2 = 18.5;
double d3 = Math.min(d1, d2);
double d4 = Math.max(d1, 11.2);

Beyond the rich set of methods provided by the Math class, there are also a couple of important constant member variables: E and PI. The E member represents the exponential number (2.7182...) used in exponential calculations. The PI member represents the value of Pi (3.1415...).

String Classes

Text strings in Java are represented with classes rather than character arrays (as they are in C and C++). The two classes that model strings in Java are String and StringBuffer. The reason for having two string classes is that the String class represents constant (immutable) strings and the StringBuffer class represents variable (mutable) strings.

The String Class

The String class is used to represent constant strings. The String class has less overhead than StringBuffer, which means that you should use it if you know that a string is constant. The constructors for the String class follow:

It should be readily apparent from the number of constructors for String that there are many ways to create String objects. The first constructor simply creates a new string that is empty. All the other constructors create strings that are initialized in different ways from various types of text data. Following are examples of using some of the String() constructors to create String objects:

String s1 = new String();
String s2 = new String("Hello");
char cArray[] = {'H', 'o', 'w', 'd', 'y'};
String s3 = new String(cArray);
String s4 = new String(cArray, 1, 3);

In the first example, an empty String object (s1) is created. In the second example, a String object (s2) is created from a literal String value, "Hello". The third example shows a String object (s3) being created from an array of characters. The fourth example shows a String object (s4) being created from a subarray of characters. The subarray is specified by passing 1 as the offset parameter and 3 as the count parameter. This means that the subarray of characters is to consist of the first three characters starting at one character into the array. The resulting subarray of characters in this case consists of the characters 'o', 'w', and 'd'.

Once you have some String objects created, you are ready to work with them using some of the powerful methods implemented in the String class. Some of the most useful methods provided by the String class follow:

The length(), charAt(), startsWith(), and endsWith() Methods

int length()char charAt(int index)
boolean startsWith(String prefix)
boolean startsWith(String prefix, int toffset)
boolean endsWith(String suffix)

The length() method simply returns the length of a string, which is the number of Unicode characters in the string. The charAt() method returns the character at a specific index of a string specified by the int parameter index. The startsWith() and endsWith() methods determine whether or not a string starts or ends with a prefix or suffix string, as specified by the prefix and suffix parameters. The second version of startsWith() enables you to specify an offset to begin looking for the string prefix. Following are some examples of using these methods:

String s1 = new String("This is a test string!");
int len = s1.length();
char c = s1.charAt(8);
boolean b1 = s1.startsWith("This");
boolean b2 = s1.startsWith("test", 10);
boolean b3 = s1.endsWith("string.");

In this series of examples, a String object is first created with the value "This is a test string!". The length of the string is calculated using the length() method and stored in the integer variable len. The length returned is 22, which specifies how many characters are contained in the string. The character at offset 8 into the string is then obtained using the charAt() method. As is true with C and C++, Java offsets start at 0, not 1. If you count eight characters into the string, you can see that charAt() returns the 'a' character. The next three examples use the startsWith() method to determine whether specific strings are located in the String object. The first startsWith() example looks for the string "This" at the beginning of the String object. This example returns true because the string is in fact located at the beginning of the String object. The second startsWith() example looks for the string "test" beginning at offset 10 into the String object. This call also returns true because the string "test" is located 10 characters into the String object. The last example uses the endsWith() method to check for the occurrence of the string "string." at the end of the String object. This call returns false because the String object actually ends with "string!".

The indexOf() and lastIndexOf() Methods

int indexOf(int ch)
int indexOf(int ch, int fromIndex)
int indexOf(String str)
int indexOf(String str, int fromIndex)
int lastIndexOf(int ch)
int lastIndexOf(int ch, int fromIndex)
int lastIndexOf(String str)
int lastIndexOf(String str, int fromIndex)

The indexOf() method returns the location of the first occurrence of a character or string within a String object. The first two versions of indexOf() determine the index of a single character within a string; the second two versions determine the index of a string of characters within a string. Each pair of indexOf() methods contains a version for finding a character or string based on the beginning of the String object, as well a version that enables you to specify an offset into the string to begin searching for the first occurrence. If the character or string is not found, indexOf() returns -1.

The lastIndexOf() methods work very much like indexOf(), with the exception that lastIndexOf()searches backwards through the string. Following are some examples of using these methods:

String s1 = new String("Saskatchewan");
int i1 = s1.indexOf('t');
int i2 = s1.indexOf("chew");
int i3 = s1.lastIndexOf('a');

In this series of examples, a String object is created with the value "Saskatchewan". The indexOf() method is then called on this string with the character value 't'. This call to indexOf() returns 5 because the first occurrence of 't' is 5 characters into the string. The second call to indexOf() specifies the string literal "chew". This call returns 6, since the substring "chew" is located 6 characters into the String object. Finally, the lastIndexOf() method is called with a character parameter of 'a'. The call to lastIndexOf() returns 10, indicating the position of the third 'a' in the string. (Remember that lastIndexOf() searches backward through the string to find the first occurrence of a character.)

The substring() Methods

String substring(int beginIndex)
String substring(int beginIndex, int endIndex)

The substring() methods return a substring of the calling String object. The first version of substring() returns the substring beginning at the index specified by beginIndex, through the end of the calling String object. The second version of substring() returns a substring beginning at the index specified by beginIndex and ending at the index specified by endIndex. Following is an example of using some of the substring() methods:

String s1 = new String("sasquatch");
String s2 = s1.substring(3);
String s3 = s1.substring(2, 7);

In this example, a String object is created with the value "sasquatch". A substring of this string is then retrieved using the substring() method and passing 3 as the beginIndex parameter. This results in the substring "quatch", which begins at the string index of 3 and continues through the rest of the string. The second version of substring() is then used with starting and ending indices of 2 and 7, yielding the substring "squat".

The equals(), equalsIgnoreCase(), and compareTo() Methods

boolean equals(Object anObject)
boolean equalsIgnoreCase(String anotherString)
int compareTo(String anotherString)

There are two methods for determining equality between String objects: equals() and equalsIgnoreCase(). The equals() method returns a boolean value based on the equality of two strings. isEqualNoCase() performs a similar function except that it compares the strings with case insensitivity. Similarly, the compareTo() method compares two strings and returns an integer value that specifies whether the calling String object is less than, greater than, or equal to the anotherString parameter. The integer value returned by compareTo() specifies the numeric difference between the two strings; it is a positive value if the calling String object is greater; it is negative if the passed String object is greater. If the two strings are equal, the return value is 0.

Wait a minute-if strings are just text, how can you get a numeric difference between two strings, or establish which one is greater than or less than the other? When strings are compared using the compareTo() method, each character is compared to the character at the same position in the other string until they don't match. When two characters are found that don't match, compareTo() converts them to integers and finds the difference. This difference is what is returned by compareTo(). Check out the following example to get a better idea of how this works:

String s1 = new String("abcfj");
String s2 = new String("abcdz");
System.out.println(s1.compareTo(s2));

Each pair of characters is compared until two are encountered that don't match. In this example, the 'f' and 'd' characters are the first two that don't match. Because the compareTo() method is called on the s1 String object, the integer value of 'd' (100) is subtracted from the integer value of 'f' (102) to determine the difference between the strings. Notice that all characters following the two nonmatching characters are ignored in the comparison.

The concat() Method

String concat(String str)

The concat() method is used to concatenate two String objects. The string specified in the str parameter is concatenated onto the end of the calling String object. Following are a few examples of string concatenation:

String s1 = new String("I saw sasquatch ");
String s2 = new String(s1 + "in Saskatchewan.");
String s3 = s1.concat("in Saskatchewan.");

In these concatenation examples, a String object is first created with the value "I saw sasquatch". The first concatenation example shows how two strings can be concatenated using the addition operator (+). The second example shows how two strings can be concatenated using the concat() method. In both examples, the resulting string is the sentence "I saw sasquatch in Saskatchewan.".

The replace() Method

String replace(char oldChar, char newChar)

The replace() method is used to replace characters in a string. All occurrences of oldChar are replaced with newChar. Using the strings from the previous concatenation examples, you can replace all the s characters with m characters like this:

String s4 = s3.replace('s', 'm');

This results in the string "I maw mamquatch in Samkatchewan.". Notice that the uppercase 'S' character wasn't replaced.

The trim(), toLowerCase(), and toUpperCase() Methods

String trim()
String toLowerCase()
String toUpperCase()

The trim() method trims leading and trailing whitespace from a String object. The toLowerCase() and toUpperCase() methods are used to convert all the characters in a String object to lowercase and uppercase. Following are some examples of these methods using the strings from the previous two examples:

String s5 = new String("\t  Yeti\n");
String s6 = s5.trim();
String s7 = s3.toLowerCase();
String s8 = s4.toUpperCase();

In this example, the trim() method is used to strip off the leading and trailing whitespace, resulting in the string "Yeti". The call to toLowerCase() results in the string "i saw sasquatch in saskatchewan.". The only characters modified were the 'I' and 'S' characters, which were the only uppercase characters in the string. The call to toUpperCase() results in the string "I MAW MAMQUATCH IN SAMKATCHEWAN.". All the lowercase characters were converted to uppercase, as you might have guessed!

The valueOf() Methods

static String valueOf(Object obj)
static String valueOf(char data[])
static String valueOf(char data[], int offset, int count)
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(float f)
static String valueOf(double d)

Finally, the valueOf()methods all return String objects that represent the particular type taken as a parameter. For example, the valueOf() method that takes an int returns the string "123" when passed the integer number 123.

The StringBuffer Class

The StringBuffer class is used to represent variable, or nonconstant, strings. The StringBuffer class is useful when you know that a string will change in value or in length. The constructors for the StringBuffer class follow:

The first constructor simply creates a new string buffer that is empty. The second constructor creates a string buffer that is length characters long, initialized with spaces. The third constructor creates a string buffer from a String object. This last constructor is useful when you need to modify a constant String object. Following are examples of using the StringBuffer constructors to create StringBuffer objects:

String s1 = new String("This is a string!");
String sb1 = new StringBuffer();
String sb2 = new StringBuffer(25);
String sb3 = new StringBuffer(s1);

Some of the most useful methods implemented by StringBuffer follow:

The length(), capacity(), and setLength() Methods

int length()
int capacity()
synchronized void setLength(int newLength)

The length() method is used to get the length of, or number of characters in, the string buffer. The capacity() method is similar to length() except that it returns how many characters a string buffer has allocated in memory, which is sometimes greater than the length. Characters are allocated for a string buffer as they are needed. Frequently, more memory is allocated for a string buffer than is actually being used. In these cases, the capacity() method returns the amount of memory allocated for the string buffer. You can explicitly change the length of a string buffer using the setLength() method. An example of using setLength() is to truncate a string by specifying a shorter length. The following example shows the effects of using these methods:

StringBuffer s1 = new StringBuffer(14);
System.out.println("capacity = " + s1.capacity());
System.out.println("length = " + s1.length());
s1.append("Bigfoot");
System.out.println(s1);
System.out.println("capacity = " + s1.capacity());
System.out.println("length = " + s1.length());
s1.setLength(3);
System.out.println(s1);
System.out.println("capacity = " + s1.capacity());
System.out.println("length = " + s1.length());

The resulting output of this example follows:

capacity = 14
length = 0
Bigfoot
capacity = 14
length = 7
Big
capacity = 14
length = 3

In this example, the newly created string buffer shows a capacity of 14 (based on the value passed in the constructor) and a length of 0. After appending the string "Bigfoot" to the buffer, the capacity remains the same but the length grows to 7, which is the length of the string. Calling setLength() with a parameter of 3 truncates the length down to 3, but leaves the capacity unaffected at 14.

The charAt() and setCharAt() Methods

synchronized char charAt(int index)
synchronized void setCharAt(int index, char ch)

The charAt() method returns the character at the location in the string buffer specified by the index parameter. You can change characters at specific locations in a string buffer using the setCharAt() method. The setCharAt() method replaces the character at index with the ch character parameter. The following example shows the use of these two methods:

StringBuffer s1 = new StringBuffer("I saw a Yeti in Yellowstone.");
char c1 = s1.charAt(9);
System.out.println(c1);
s1.setCharAt(4, 'r');
System.out.println(s1);

In this example, the call to charAt() results in the character 'e', which is located 9 characters into the string. The call to setCharAt() results in the following output, based on the 'w' in "saw" being replaced by 'r':

I sar a Yeti in Yellowstone.

The append() and insert() Methods

synchronized StringBuffer append(Object obj)
synchronized StringBuffer append(String str)
synchronized StringBuffer append(char c)
synchronized StringBuffer append(char str[])
synchronized StringBuffer append(char str[], int offset, int len)
StringBuffer append(boolean b)
StringBuffer append(int I)
StringBuffer append(long l)
StringBuffer append(float f)
StringBuffer append(double d)
synchronized StringBuffer insert(int offset, Object obj)
synchronized StringBuffer insert(int offset, String str)
synchronized StringBuffer insert(int offset, char c)
synchronized StringBuffer insert(int offset, char str[])
StringBuffer insert(int offset, boolean b)
StringBuffer insert(int offset, int I)
StringBuffer insert(int offset, long l)
StringBuffer insert(int offset, float f)
StringBuffer insert(int offset, double d)

The StringBuffer class implements a variety of overloaded append() and insert() methods. The append() methods allow you to append various types of data onto the end of a String object. Each append() method returns the String object on which it was called. The insert() methods enable you to insert various data types at a specific offset in a string buffer. insert() works in a manner similar to append(), with the exception of where the data is placed. Following are some examples of using append() and insert():

StringBuffer sb1 = new StringBuffer("2 + 2 = ");
StringBuffer sb2 = new StringBuffer("The tires make contact ");
sb1.append(2 + 2);
sb2.append("with the road.");
sb2.insert(10, "are the things on the car that ");

In this set of examples, two string buffers are first created using the constructor for StringBuffer that takes a string literal. The first StringBuffer object initially contains the string "2 + 2 = ". The append() method is used to append the result of the integer calculation 2 + 2. In this case, the integer result 4 is converted by the append() method to the string "4" before it is appended to the end of the StringBuffer object. The value of the resulting StringBuffer object is "2 + 2 = 4". The second string buffer object begins life with the value "The tires make contact ". The string "with the road." is then appended onto the end of the string buffer using the append() method. Then the insert() method is used to insert the string "are the things on the car that ". Notice that this string is inserted at index 10 within the StringBuffer object. The string that results after these two methods are called follows:

The tires are the things on the car that make contact with the road.

The toString() Method

String toString()

The last method of interest in the StringBuffer class is the toString() method. toString() returns the String object representation of the calling StringBuffer object. toString() is useful when you have a StringBuffer object but need a String object.

System and Runtime Classes

The System and Runtime classes provide access to the system and runtime environment resources. The System class is defined as final and is composed entirely of static variables and methods, which means that you never actually instantiate an object of it. The Runtime class provides direct access to the runtime environment and is useful for executing system commands and determining things like the amount of available memory.

The System Class

The System class contains the following useful methods:

The currentTimeMillis() Method

static long currentTimeMillis()

The currentTimeMillis() method returns the current system time in milliseconds. The time is specified in GMT (Greenwich Mean Time) and reflects the number of milliseconds that have elapsed since midnight on January 1, 1970. This is a standard frame of reference for computer time representation.

The arraycopy() Method

static void arraycopy(Object src, int src_position, Object dst,
  int dst_position, int length)

The arraycopy() method copies data from one array to another. arraycopy() copies length elements from the src array beginning at position src_position to the dst array starting at dst_position.

The getProperties(), getProperty(), and setProperties() Methods

static Properties getProperties()
static String getProperty(String key)
static String getProperty(String key, String def)
static void setProperties(Properties props)

The getProperties() method gets the current system properties and returns them using a Properties object. There are also two getProperty() methods in System that allow you to get individual system properties. The first version of getProperty() returns the system property matching the key parameter passed into the method. The second version of getProperty() does the same as the first except that it returns the default def parameter if the property isn't found. The setProperties() method takes a Properties object and sets the system properties with it.

The gc() Method

static void gc()

The gc() method stands for garbage collection and does exactly that. gc() forces the Java runtime system to perform a memory garbage collection. You can call gc() if you think the system is running low on memory, because a garbage collection usually frees up memory.

The loadLibrary() Method

static void loadLibrary(String libname)

The Java system supports executable code in dynamic link libraries. A dynamic link library is a library of Java classes that can be accessed at run time. The loadLibrary() method is used to load a dynamic link library. The name of the library to load is specified in the libname parameter.

The System class contains three member variables that are very useful for interacting with the system: in, out, and err. The in member is an InputStream object that acts as the standard input stream. The out and err members are PrintStream objects that act as the standard output and error streams.

The Runtime Class

The Runtime class is another very powerful class for accessing Java system-related resources. Following are a few of the more useful methods in the Runtime class:

The getRuntime(), freeMemory(), and totalMemory() Methods

static Runtime getRuntime()
long freeMemory()
long totalMemory()

The static method getRuntime() returns a Runtime object representing the runtime system environment. The freeMemory() method returns the amount of free system memory in bytes. Because freeMemory() returns only an estimate of the available memory, it is not completely accurate. If you need to know the total amount of memory accessible by the Java system, you can use the totalMemory() method. The totalMemory() method returns the number of bytes of total memory; the freeMemory() method returns the number of bytes of available memory. Listing 12.1 contains the source code for the Memory program, which displays the available free memory and total memory.


Listing 12.1. The Memory class.

class Memory {
  public static void main (String args[]) {
    Runtime runtime = Runtime.getRuntime();
    long freeMem = runtime.freeMemory() / 1024;
    long totalMem = runtime.totalMemory() / 1024;
    System.out.println("Free memory : " + freeMem + "KB");
    System.out.println("Total memory : " + totalMem + "KB");
  }
}

An example of the output of running the Memory program follows:

Free Memory : 3068KB
Total Memory : 3071KB

The Memory class uses the getRuntime(), freeMemory(), and totalMemory() methods of the Runtime class. Note that you can convert the amount of memory returned by each method from bytes to kilobytes by dividing by 1024.

The gc() and loadLibrary() Methods

void gc()
synchronized void loadLibrary(String libname)

The other two methods of importance in the Runtime class (gc() and loadLibrary()) work exactly the same as the versions belonging to the System class.

Class Classes

Java provides two classes in the language package for dealing with classes: Class and ClassLoader. The Class class allows you access to the runtime information for a class. The ClassLoader class provides support for dynamically loading classes at run time.

The Class Class

Some of the more useful methods implemented by the Class class follow:

The forName() Method

static Class forName(String className)

The forName() method is a static method used to get the runtime class descriptor object for a class. The String parameter className specifies the name of the class about which you want information. forName() returns a Class object containing runtime information for the specified class. Notice that forName() is static and is the method you typically use to get an instance of the Class class for determining class information. Following is an example of how to use the forName() method to get information about the StringBuffer class:

Class info = Class.forName("java.lang.StringBuffer");

The getName() Method

String getName()

The getName() method retrieves the string name of the class represented by a Class object. Following is an example of using the getName() method:

String s = info.getName();

The getSuperClass(), getClassLoader(), and isInterface() Methods

Class getSuperclass()
ClassLoader getClassLoader()
boolean isInterface()

The getSuperclass() method returns a Class object containing information about the superclass of an object. The getClassLoader() method returns the ClassLoader object for a class or null if no class loader exists. The isInterface() method returns a boolean indicating whether or not a class is an interface.

The toString() Method

String toString()

Finally, the toString() method returns the name of a class or interface. toString() automatically prepends the string "class" or "interface" to the name based on whether the Class
object represents a class or an interface.

The ClassLoader Class

The ClassLoader class provides the framework that enables you to dynamically load classes into the runtime environment. Following are the methods implemented by ClassLoader:

The loadClass() and defineClass() Methods

abstract Class loadClass(String name, boolean resolve)
final Class defineClass(byte data[], int offset, int length)

The loadClass() method is an abstract method that must be defined in a subclass of ClassLoader. loadClass() resolves a class name passed in the String parameter name into a Class runtime object. loadClass() returns the resulting Class on success or null if not successful. The defineClass() method converts an array of byte data into a Class object. The class is defined by the data parameter beginning at offset and continuing for length bytes.

The resolveClass() Method

final void resolveClass(Class c)

A class defined with defineClass() must be resolved before it can be used. You can resolve a class by using the resolveClass() method, which takes a Class object as its only parameter.

The findSystemClass() Method

final Class findSystemClass(String name)

Finally, the findSystemClass()method is used to find and load a system class. A system class is a class that uses the built-in (primordial) class loader, defined as null.

Summary

In this chapter, you learned a great deal about the classes and interfaces that make up the Java language package. The language package lays out the core classes, interfaces, and errors of the Java class libraries. Although some of the classes implemented in the language package are fairly low level, a solid understanding of these classes is necessary to move on to other areas of the Java class libraries.

This chapter explained how fundamental data types can become objects using the data type wrappers. You then learned about the many mathematical functions contained in the Math class. And don't forget about the string classes, which provide a powerful set of routines for working with strings of text. You finished up with a tour of how to access the system and runtime resources of Java, along with the lower-level runtime and dynamic class support.

The following chapter provides the next stop on this guided tour of the Java class libraries: the Java utilities package.