Code reuse is one of the most significant benefits of using object-oriented design practices. Creating reusable, inheritable classes can save amazing amounts of time and energy, which in turn greatly boosts productivity. Java itself takes code reuse to heart in its implementation of a wide variety of standard objects that are available to Java programmers. The standard Java objects are known collectively as the Java class libraries.
The Java class libraries are implemented as packages, which contain groups of related classes. Along with classes, the standard Java packages also include interfaces, exception definitions, and error definitions. Java is composed of three class libraries, or packages: the language package, the utilities package, and the I/O package. In this chapter, you learn what these packages are and what classes and interfaces comprise each.
NOTE |
---|
There actually are three other standard packages that are important in Java programming, but they arent technically considered part of the basic Java class libraries. Youll learn about these packages in Part V, Applet Programming, and Part VI, Network Programming. |
The Java language package, which is also known as java.lang, provides classes that make up the core of the Java language. The language package contains classes at the lowest level of the Java class libraries. For example, the Object class, which all classes are derived from, is located in the language package.
Its impossible to write a Java program without dealing with at least a few of the elements of the language package. Youll learn much more about the inner workings of the language package in the next chapter. The most important classes contained in the language package follow:
The Object class is the superclass for all classes in Java. Because all classes are derived from Object, the methods defined in Object are shared by all classes. This results in a core set of methods that all Java classes are guaranteed to support. Object includes methods for making copies of an object, testing objects for equality, and converting the value of an object to a string.
The fundamental data types (int, char, float, and so on) in Java are not implemented as classes. Many times it is useful, however, to know more information about a fundamental type than just its value. By implementing class wrappers for the fundamental types, additional information can be maintained, as well as methods defined that act on the types. The data type wrapper classes serve as class versions of the fundamental data types, and are named similarly to the types they wrap. For example, the type wrapper for int is the Integer class. Following are the Java data type wrapper classes:
Type wrappers are also useful because many of Javas utility classes require classes as parameters, not simple types. It is worth pointing out that type wrappers and simple types are not interchangeable. However, you can get a simple type from a wrapper through a simple method call, which youll learn about in the next chapter.
The Math class serves as a grouping of mathematical functions and constants. It is interesting to note that all the variables and methods in Math are static, and the Math class itself is final. This means you cant derive new classes from Math. Additionally, you cant instantiate the Math class. Its best to think of the Math class as just a conglomeration of methods and constants for performing mathematical computations.
The Math class includes the E and PI constants, methods for determining the absolute value of a number, methods for calculating trigonometric functions, and minimum and maximum methods, among others.
For various reasons (mostly security related), Java implements text strings as classes, rather than forcing the programmer to use character arrays. The two Java classes that represent strings are String and StringBuffer. The String class is useful for working with constant strings that cant change in value or length. The StringBuffer class is used to work with strings of varying value and length.
The System and Runtime classes provide a means for your programs to access system and runtime environment resources. Like the Math class, the System class is final and is entirely composed of static variables and methods. The System class basically provides a system-independent programming interface to system resources. Examples of system resources include the standard input and output streams, System.in and System.out, which typically model the keyboard and monitor.
The Runtime class provides direct access to the runtime environment. An example of a run-time routine is the freeMemory method, which returns the amount of free system memory available.
Java is a multithreaded environment and provides various classes for managing and working with threads. Following are the classes and interfaces used in conjunction with multithreaded programs:
The Thread class is used to create a thread of execution in a program. The ThreadDeath class is used to clean up after a thread has finished execution. As its name implies, the ThreadGroup class is useful for organizing a group of threads. Finally, the Runnable interface provides an alternate means of creating a thread without subclassing the Thread class. Threads and multithreading are covered in detail in Chapter 15, Threads and Multithreading.
Java provides two classes for working with classes: Class and ClassLoader. The Class class provides runtime information for a class, such as the name, type, and parent superclass. Class is useful for querying a class for runtime information, such as the class name. The ClassLoader class provides a means to load classes into the runtime environment. ClassLoader is useful for loading classes from a file or for loading distributed classes across a network connection.
Runtime error handling is a very important facility in any programming environment. Java provides the following classes for dealing with runtime errors:
The Throwable class provides low-level error-handling capabilities such as an execution stack list. The Exception class is derived from Throwable and provides the base level of functionality for all the exception classes defined in the Java system. The Exception class is used for handling normal errors. The Error class is also derived from Throwable, but it is used for handling abnormal errors that arent expected to occur. Very few Java programs worry with the Error class; most use the Exception class to handle runtime errors. Error handling with exceptions is covered in detail in Chapter 16, Exception Handling.
Java supports system processes with a single class, Process. The Process class represents generic system processes that are created when you use the Runtime class to execute system commands.
The Java utilities package, which is also known as java.util, provides various classes that perform different utility functions. The utilities package includes a class for working with dates, a set of data structure classes, a class for generating random numbers, and a string tokenizer class, among others. Youll learn much more about the classes that make up the utilities package in Chapter 19, The Utilities Package. The most important classes contained in the utilities package follow:
The Date class represents a calendar date and time in a system-independent fashion. The Date class provides methods for retrieving the current date and time as well as computing days of the week and month.
The Java data structure classes and interfaces implement popular data structures for storing data. The data structure classes and interfaces are as follows:
The BitSet class represents a set of bits, which is also known as a bitfield. The Dictionary class is an abstract class that provides a lookup mechanism for mapping keys to values. The Hashtable class derives from Dictionary and provides additional support for working with keys and values. The Properties class is derived from Hashtable and provides the additional functionality of being readable and writable to and from streams. The Vector class implements an array that can dynamically grow. The Stack class derives from Vector and implements a classic stack of last-in-first-out (LIFO) objects. Finally, the Enumeration interface specifies a set of methods for counting (iterating) through a set of values.
Many programs, especially programs that model the real world, require some degree of randomness. Java provides randomness by way of the Random class. The Random class implements a random-number generator by providing a stream of pseudo-random numbers. A slot machine program is a good example of one that would make use of the Random class.
The StringTokenizer class provides a means of converting text strings into individual tokens. By specifying a set of delimiters, you can parse text strings into tokens using the StringTokenizer class. String tokenization is useful in a wide variety of programs, from compilers to text-based adventure games.
The model-view paradigm is becoming increasingly popular in object-oriented programming. This model breaks a program down into data and views on the data. Java supports this model with the Observable class and the Observer interface. The Observable class is subclassed to define the observable data in a program. This data is then connected to one or more observer classes. The observer classes are implementations of the Observer interface. When an Observable object changes state, it notifies all of its observers of the change.
The Java I/O package, also known as java.io, provides classes with support for reading and writing data to and from different input and output devices, including files. The I/O package includes classes for inputting streams of data, outputting streams of data, working with files, and tokenizing streams of data. Youll learn a lot more about the classes that make up the I/O package in Chapter 20, The I/O Package. The most important classes contained in the I/O package follow:
Java uses input streams to handle reading data from an input source. An input source can be a file, a string, memory, or anything else that contains data. The input stream classes follow:
The InputStream class is an abstract class that serves as the base class for all input streams. The InputStream class defines an interface for reading streamed bytes of data, finding out the number of bytes available for reading, and moving the stream position pointer, among other things. All the other input streams provide support for reading data from different types of input devices.
Output streams are the counterpart to input streams and handle writing data to an output source. Similar to input sources, output sources include files, strings, memory, and anything else that can contain data. The output stream classes defined in java.io follow:
The OutputStream class is an abstract class that serves as the base class for all output streams. OutputStream defines an interface for writing streamed bytes of data to an output source. All the other output streams provide support for writing data to different output devices. Data written by an output stream is formatted to be read by an input stream.
Files are the most widely used method of data storage in computer systems. Java supports files with two different classes: File and RandomAccessFile. The File class provides an abstraction for files that takes into account system-dependent features. The File class keeps up with information about a file including the location where it is stored and how it can be accessed. The File class has no methods for reading and writing data to and from a file; it is only useful for querying and modifying the attributes of a file. In actuality, you can think of the File class data as representing a filename, and the class methods as representing operating system commands that act on filenames.
The RandomAccessFile class provides a variety of methods for reading and writing data to and from a file. RandomAccessFile contains many different methods for reading and writing different types of information, namely the data type wrappers.
The StreamTokenizer class provides the functionality for converting an input stream of data into a stream of tokens. StreamTokenizer provides a set of methods for defining the lexical syntax of tokens. Stream tokenization can be useful in parsing streams of textual data.
This chapter provided a thumbnail sketch of the contents of the three Java class libraries: the language package, the utilities package, and the I/O package. Although you didnt learn a lot of gritty details, or how to use any classes in a real program, you hopefully now have a broad picture in your mind of what these packages can do. The Java class libraries provide a rich set of classes for overcoming a wide variety of programming obstacles.
A common problem when using programming environments with a lot of support libraries is knowing what functionality is provided and what functionality you must write yourself. This chapter hopefully has given you an idea of what standard classes you can reuse in your own Java programs, and what classes you will have to implement yourself.
Having seen what each package in the Java class libraries contain, youre probably eager to get busy learning how to use the classes in each. The next three chapters each focus on one of the three packages that make up the Java class libraries.