Skip to main content.

Web Based Programming Tutorials

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

Java Unleashed

Java Unleashed--ch18.htm Previous Page TOC Index Next Page

Chapter 18

The language package

The Java language package is at 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 many of the classes in the language package to be indispensable in writing Java programs.



The language package contains many classes, each with a variety of member variables and methods. You won’t learn about every class and every method in this chapter, as it would simply be too much material to cover in a single chapter. Rather, you will focus on the most important classes in the language package; classes that will 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. This is because Chapters 15 and 16 are devoted to them.

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, as all the classes you develop will inherit the variables and methods of Object. The Object class implements the following important methods:

The Object clone() creates a clone of the object it is called on. clone creates and allocates memory for the new object that is 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 by circle1 calling the clone method to create a clone of itself.

The equals method compares two objects for equality. equals is only applicable when both objects have been stored in a Hashtable. The hashCode method returns the hashcode value for an object. Hashcodes are integers that uniquely represent objects in the Java system.

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

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 could be very valuable for determining the internal state of an object when debugging.

Data Type Wrapper Classes

The data type wrapper classes serve to 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. Following are the type wrapper classes supported by Java:



Although each wrapper implements methods specific to each data type, there are a handful of methods applicable 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 is actually the creation method for each class. The wrapper creation methods 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 would use the creation method for the Character class like this:

Character c1 = new Character(‘x’);

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, 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.

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 is used to get a string representation of the internal state of an object. toString is typically overridden in each class so as to reflect unique state implementations. Following is an example of how you might output the state of a wrapper variable using toString:

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

The equals method is used to test for equality between two wrapper objects. This is the same equals method implemented in Object and inherited by all other objects in Java. The valueOf method is implemented in all of 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 of 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:

static boolean getBoolean(String name)

getBoolean 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, which specifies the name of the operating system the Java runtime is executing in. In my case, os.name is set to “Windows 95”.

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, while 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 return whether or not a character is an uppercase or lower case 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 simply returns whether or not a character is a digit (0-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 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 character is considered whitespace.

The toLowerCase and toUpperCase methods convert a character to a lower 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’ because of the call to the toUpperCase method. In the second example, c2 is converted from ‘M’ to ‘m’ because of the call to toLowerCase.

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 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.

The Character class provides two final static data members for specifying the radix limits for conversions: MIN_RADIX and MAX_RADIX. MIN_RADIX specifies the minimum radix (2) for performing numeric to character conversions and vice-versa. Likewise, MAX_RADIX specifies the maximum radix (36) for conversions.

Integer 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 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 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 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 you don’t need 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 value val.

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 object is very similar to the Integer object except 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 return 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 return 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 methods, isInfinity 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 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 results in the floating point value 5.237 being converted to the long value 5.

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.

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 object is very similar to the Float object. 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 so you can’t derive from it. The most useful methods implemented by the Math class follow:

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’ll learn about the PI constant member variable of Math at the end of this section.

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 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, where 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 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 as a double value.

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 return the absolute value of numbers of varying types. There are versions of abs for working with 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 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 is an example 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, where PI represents the value of Pi (3.1415...).

String Classes

Unlike C and C++, text strings in Java are represented with classes rather than character arrays. 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 you should try to use it if you know that a string is constant. The creation methods for the String class follow:

It is readily apparent from the number of creation methods for String that there are many ways to create String objects. The first creation method simply creates a new string that is empty. All of the other creation methods create strings that are initialized in different ways from various types of text data. Following are examples of using some of the String creation methods 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 aString object (s3) being created from an array of characters. Finally, 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 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. Like 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 if 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 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 ten 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 methods return 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, while the second two versions determine the index of a string of characters within a string. Each pair of indexOf methods contain 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 93"Saskatchewan”. The indexOf method is then called on this string with the character value ‘t’. This call to indexOf returns 5, since the first occurrence of ‘t’ is five characters into the string. The second call to indexOf specifies the string literal “chew”. This call returns 6, since the substring “chew” is located six 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 third ‘a’ in the string. Remember, lastIndexOf searches backward through the string to find the first occurrence of a character.

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 one 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 three 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”.

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 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, and 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. Since 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 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 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 could replace all of 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 method trims leading and trailing whitespace off of a String object. The toLowerCase and toUpperCase methods are used to convert all of the characters in a String object to lower and uppercase. Following are some examples of using 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 character modified was the ‘I’ character, which was the only uppercase character in the string. The call to toUpperCase results in the string “I MAW MAMQUATCH IN SAMKATCHEWAN.”. All of the lowercase characters were converted to uppercase, as you might have guessed!

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 will return the string “123” when passed the integer number 123.

The StringBuffer Class

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

The first creation method simply creates a new string buffer that is empty. The second creation method creates a string buffer that is length characters long, initialized with spaces. The third creation method creates a string buffer from a String object. This last creation method is useful when you need to modify a constant String object. Following are examples of using the StringBuffer creation methods 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 method is used to get the length, or number of characters in the string buffer. The capacity method is similar to length except 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. Many times more memory is allocated for a string buffer than is actually being used. In these cases, the capacity method will return 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 would be to truncate a string by specifying a shorter length. The following example illustrates 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 creation method) 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 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 illustrates 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 StringBuffer class implements a variety of overloaded append 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 that it was called on. The insert methods enable you to insert various data types at a specific offset in a string buffer. insert works very 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 creation method 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 resulting string after these two methods are called follows:

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

The last method of interest in StringBuffer 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 you will 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 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 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 method gets the current system properties and returns them via 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 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 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, since a garbage collection will usually free up memory.

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 runtime. 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 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, where the freeMemory method returns the number of bytes of available memory. Listing 18.1 contains the source code for the Memory program, which displays the available free memory and total memory.

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 the amount of memory returned by each method is converted from bytes to kilobytes by dividing by 1024.

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 runtime.

The Class Class

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

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 you want information for. forName returns a Class object containing runtime information for the specified class. Notice that forName is static and is the method you typically will 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 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 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.

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 for enabling you to dynamically load classes into the runtime environment. Following are the methods implemented by ClassLoader:

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. 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.

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, which is 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.

You learned in this chapter 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 next chapter provides the next stop on this guided tour of the Java class libraries, which is the Java utilities package.


Previous Page TOC Index Next Page