Java Institute DreamsCity 2000
Welcome to DreamsCity
Return to Java Institute

USING JAVA.LANG.CLASS

These tips were developed using Java(tm) 2 SDK, Standard Edition, 
v 1.2.2.


In object-oriented programming, a class is a user-defined type, 
with a set of methods that operate on instances (objects) of the 
class. For example, you might have a class Point in an application:
public class Point { int x; int y; } and the application operates on instances of Point, like (37,47) and (153,89). java.lang.Class is one of the standard classes in the Java programming language, and instances of java.lang.Class represent other classes and interfaces. This tip could use Class to refer to java.lang.Class, but that terminology might be confusing. So you'll see java.lang.Class throughout the discussion. java.lang.Class gives you the ability to find out information about classes that are currently loaded into the Java(tm) Virtual Machine* (JVM). It also gives you a way to dynamically load additional classes into your application. Here's an example, it's a short application that uses java.lang.Class features: public class ClassDemo1 { public static void main(String args[]) { Class cls = null; // load a class by name (like java.util.ArrayList) try { cls = Class.forName(args[0]); } catch (ClassNotFoundException exc) { System.err.println(exc); } // display the hierarchy back to java.lang.Object do { System.out.println(cls); cls = cls.getSuperclass(); } while (cls != null); } } This program uses Class.forName to load a class into the JVM; if the class is already loaded, it finds the java.lang.Class instance that represents the class. Then the program calls Class.getSuperclass repeatedly to find the class's superclass. The result of this process is the class hierarchy for a given class. For example, if you invoke the program with an argument of "java.util.ArrayList", the output is: class java.util.ArrayList class java.util.AbstractList class java.util.AbstractCollection class java.lang.Object which is the class hierarchy of ArrayList up through java.lang.Object. In other words, you can find out about the class properties of ArrayList from within a running program. java.lang.Class is a class whose instances represent other Java classes and interfaces, such as ArrayList, String, and Cloneable. java.lang.Class doesn't have a public constructor, so you can't say: Class c = new Class(...); Instead, you obtain java.lang.Class instance references using Class.forName as illustrated above. Class.forName is used to load a class at run time, based on a string containing the class name (such as "java.util.ArrayList"). Another way you can obtain a java.lang.Class instance reference is to use the ".class" notation, as in: Class c = java.lang.String.class; Because Java arrays fit into the class hierarchy rooted at java.lang.Object, you can also say: Class c = int[].class; A final way to obtain a java.lang.Class reference is through an object reference. In this case, you say: Class c = obj.getClass(); or: int vec[] = new int[10]; Class c = vec.getClass(); Once you have a java.lang.Class instance reference, you can create new instances of the class that it represents. Here's an example: public class ClassDemo2 { public static void main(String args[]) { Class cls = null; Object obj = null; // load a class by name try { cls = Class.forName(args[0]); } catch (ClassNotFoundException exc) { System.err.println(exc); } // create a new instance of that class try { obj = cls.newInstance(); } catch (IllegalAccessException exc1) { System.err.println(exc1); } catch (InstantiationException exc2) { System.err.println(exc2); } } } Class.newInstance is used to create new instances of the class represented by the java.lang.Class instance. It assumes the existence of a default (no parameter) constructor for the class. You could ask why you can't simply use "new" to create a new class instance, and not go to all the trouble of using java.lang.Class and newInstance. The key point about the above approach is that it's dynamic; you can load classes by name into a program and create new instances of these classes. If you load classes using a string name, like "pkg.classname", then you might wonder how the loaded classes are manipulated. One way is to program in terms of interfaces. Suppose that you have an interface A, and two classes B and C that implement that interface. Class B uses an implementation that is the most space efficient, while class C uses more space but runs faster than B. You can dynamically load B or C, but then program in terms of the interface A. So the line above that reads: obj = cls.newInstance(); might better read: A aref = null; ... load B or C by name ... aref = (A)cls.newIntance(); A complete example looks like this: // file A.java public interface A { void f(); } // file B.java public class B implements A { public void f() { System.out.println("B.f"); } } // file C.java public class C implements A { public void f() { System.out.println("C.f"); } } // file ClassDemo3.java public class ClassDemo3 { public static void main(String args[]) { A aref = null; Class cls = null; // load a class (B or C) try { cls = Class.forName(args[0]); } catch (ClassNotFoundException exc) { System.err.println(exc); } // create a new instance of that class try { aref = (A)cls.newInstance(); } catch (IllegalAccessException exc1) { System.err.println(exc1); } catch (InstantiationException exc2) { System.err.println(exc2); } // call f() in the loaded class aref.f(); } } If you say: $ java ClassDemo3 C then the output is: C.f that is, the f method in the loaded class C is called through the interface reference. In ClassDemo1 above, getSuperclass finds the superclass of a class represented by a java.lang.Class instance. There are other query methods that you can use with java.lang.Class. For example, a common one is illustrated by this program: public class ClassDemo4 { public static void classify(Object obj) { if (obj == null) { System.out.println("null"); } else if (obj.getClass().isArray()) { System.out.println("array"); } else { System.out.println("non-array"); } } public static void main(String args[]) { classify(null); classify(new int[10]); classify(new String()); } } In this example there's an object reference passed to the classify method, and you'd like to know whether it represents an array. A final area worth mentioning is reflection. The Java system defines a separate package for reflection (java.lang.reflect), but it relies on methods found in java.lang.Class. One way to distinguish java.lang.reflect facilities from those in java.lang.Class is to note that the java.lang.reflect operates on individual fields and methods in a class instance. java.lang.Class is concerned with a class as a whole unit. For example, this program displays a list of all the public methods found in String: import java.lang.reflect.*; public class ClassDemo5 { public static void main(String args[]) { Class cls = java.lang.String.class; Method methlist[] = cls.getMethods(); for (int i = 0; i < methlist.length; i++) System.out.println(methlist[i]); } } java.lang.reflect.Method is a class found in the reflection package. Class.getMethods gets a list of all the methods in the class. You could go deeper into the internals of a method, for example, you could obtain a list of all the method's parameters in a form that could be manipulated within an application. To do that, you would use facilities such as Method.getParameterTypes. In other words, in this simple demo program, the names of all methods and their parameters are displayed. However, to find out which of the methods has a third parameter of type "int", use reflection facilities within java.lang.reflect.Method. java.lang.Class is a powerful mechanism for examining the properties of classes, and for dynamically loading and manipulating those classes.

Any comments? email to:
richard@dreamscity.net