The Class Class

   

Core Java™ 2: Volume I - Fundamentals
By Cay S. Horstmann, Gary Cornell
Table of Contents
Chapter 5.  Inheritance


The Class Class

While your program is running, the Java runtime system always maintains what is called runtime type identification on all objects. This information keeps track of the class to which each object belongs. Runtime type information is used by the virtual machine to select the correct methods to execute.

However, you can also access this information by working with a special Java class. The class that holds this information is called, somewhat confusingly, Class. The getClass() method in the Object class returns an instance of Class type.

 Employee e; . . . Class cl = e.getClass(); 

Just like an Employee object describes the properties of a particular employee, a Class object describes the properties of a particular class. Probably the most commonly used method of Class is getName. This returns the name of the class. For example, the statement

 System.out.println(e.getClass().getName() + " " + e.getName()); 

prints

 Employee Harry Hacker 

if e is an employee, or

 Manager Harry Hacker 

if e is a manager.

You can also obtain a Class object corresponding to a string by using the static forName method.

 String className = "Manager"; Class cl = Class.forName(className); 

You would use this method if the class name is stored in a string that varies at run time. This works if className is the name of a class or interface. Otherwise, the forName method throws a checked exception. See the sidebar on exceptions to see how you need to supply an exception handler whenever you use this method.

graphics/exclamatory_icon.gif

At startup, the class containing your main method is loaded. It loads all classes that it needs. Each of those loaded classes loads the classes that they need, and so on. That can take a long time for a big application, frustrating the user. You can give users of your program the illusion of a faster start, with the following trick. Make sure that the class containing the main method does not explicitly refer to other classes. First display a splash screen. Then manually force the loading of other classes by calling Class.forName.

A third method for obtaining an object of type Class is a convenient shorthand. If T is any Java type, then T.class is the matching class object. For example:

 Class cl1 = Manager.class; Class cl2 = int.class; Class cl3 = Double[].class; 

Note that a Class object really describes a type, which may or may not be a class. For example, int is not a class, but int.class is nevertheless an object of type Class.

graphics/notes_icon.gif

For historical reasons, the getName method returns somewhat strange names for array types:

 System.out.println(Double[].class.getName());    // prints [Ljava.lang.Double; System.out.println(int[].class.getName());    // prints [I 

The virtual machine manages a unique Class object for each type. Therefore, you can use the == operator to compare class objects, for example:

 if (e.getClass() == Employee.class) . . . 

Another example of a useful method is one that lets you create an instance of a class on the fly. This method is called, naturally enough, newInstance(). For example,

 e.getClass().newInstance(); 

creates a new instance of the same class type as e. The newInstance method calls the default constructor (the one that takes no parameters) to initialize the newly created object.

Using a combination of forName and newInstance lets you create an object from a class name stored in a string.

 String s = "Manager"; Object m = Class.forName(s).newInstance(); 

Catching Exceptions

We will cover exception handling fully in Chapter 11, but in the meantime you will occasionally encounter methods that threaten to throw exceptions.

When an error occurs at run time, a program can "throw an exception." Throwing an exception is more flexible than terminating the program because you can provide a handler that "catches" the exception and deals with it.

If you don't provide a handler, the program still terminates and prints a message to the console, giving the type of the exception. You may already have seen exception reports when you accidentally used a null reference or overstepped the bounds of an array.

There are two kinds of exceptions: unchecked exceptions and checked exceptions. With checked exceptions, the compiler checks that you provide a handler. However, many common exceptions, such as accessing a null reference, are unchecked. The compiler does not check whether you provide a handler for these errors after all, you should spend your mental energy on avoiding these mistakes rather than coding handlers for them.

But not all errors are avoidable. If an exception can occur despite your best efforts, then the compiler insists that you provide a handler. The Class.forName method is an example of a method that throws a checked exception. In Chapter 11, you will see several exception handling strategies. For now, we'll just show you the simplest handler implementation.

Place one or more methods that might throw checked exceptions inside a try block. Then provide the handler code in the catch clause.

 try {    statements that might throw exceptions } catch(Exception e) {    handler action } 

Here is an example:

 try {  String name = . . .; // get class name    Class cl = Class.forName(name); // might throw exception    . . . // do something with cl } catch(Exception e) {    e.printStackTrace(); } 

If the class name doesn't exist, the remainder of the code in the try block is skipped, and the program enters the catch clause. (Here, we print a stack trace by using the printStackTrace method of the Throwable class. Throwable is the superclass of the Exception class.) If none of the methods in the try block throw an exception, then the handler code in the catch clause is skipped.

You only need to supply an exception handler for checked exceptions. It is easy to find out which methods throw checked exceptions the compiler will complain whenever you call a method that threatens to throw a checked exception and you don't supply a handler.

graphics/notes_icon.gif

If you need to provide parameters for the constructor of a class you want to create by name in this manner, then you can't use statements like the above. Instead, you must use the newInstance method in the Constructor class. (This is one of several classes in the java.lang.reflect package. We will discuss reflection in the next section.)

graphics/cplus_icon.gif

The newInstance method corresponds to the idiom of a virtual constructor in C++. However, virtual constructors in C++ are not a language feature but just an idiom that needs to be supported by a specialized library. The Class class is similar to the type_info class in C++, and the getClass method is equivalent to the typeid operator. The Java Class is quite a bit more versatile than type_info, though. The C++ type_info can only reveal a string with the name of the type, not create new objects of that type.

java.lang.Class 1.0

graphics/api_icon.gif
  • static Class forName(String className)

    returns the Class object representing the class with name className.

  • Object newInstance()

    returns a new instance of this class.

java.lang.reflect.Constructor 1.1

graphics/api_icon.gif
  • Object newInstance(Object[] args)

    constructs a new instance of the constructor's declaring class.

    Parameters:

    args

    the parameters supplied to the constructor. See the section on reflection for more information on how to supply parameters.

java.lang.Throwable 1.0

graphics/api_icon.gif
  • void printStackTrace()

    prints the Throwable object and the stack trace to the standard error stream.


       
    Top
     



    Core Java 2(c) Volume I - Fundamentals
    Building on Your AIX Investment: Moving Forward with IBM eServer pSeries in an On Demand World (MaxFacts Guidebook series)
    ISBN: 193164408X
    EAN: 2147483647
    Year: 2003
    Pages: 110
    Authors: Jim Hoskins

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net