Before I leap into explaining to use Class.forName,
I want to give you an idea of what it is for:
- You want to write a program that composes Java programs, compiles them, then
executes them, on the fly, without human intervention. It might generate
thousands of such little programs. You need to be able to execute class files
that did not exist when your calling code was written.
- You want to write a program that generates JVM byte codes, class file images in
RAM, then executes them, without ever writing the *.class
file to disk. For this you also need to write a custom ClassLoader
since the standard one does not look in RAM, only on disk in the classpath.
- You want write a program such as the HolidayCalculator which comes with modules
for computing a few dozen Holidays. You want to make it possible for users of
the program to easily add more holiday calculator plug-ins for obscure holidays
without having to look at, modify or recompile any source code.
- You want to write a BeanBox editor that can take any Bean-compliant class and
execute it and edit its fields. For this you also need Reflection to find out
what get/set methods are available.
- You want to write a spreadsheet
amanuensis, a simple, flexible, high performance spreadsheet component.
Now let’s look under the hood to understand how the various tools work. There
are Class objects (objects of class Class)
that represent classes (including arrays), interfaces, and primitives. The Class.newInstance
method lets you create new objects of that class without requiring a variable
declared specifically of that class. You are using the default public no arg
constructor. Your class had better have one. This allows code to be much more
open ended than in other languages, with new variants added dynamically. The Class.getName
method lets you display the class name. There are also methods to discover the
details of the fields and methods associated with the class in the java.lang.reflect.*
package.
Class.forName eagerly
loads the class if it not already loaded. Inside the JVM there is a HashMap
of all the classes that have been previously loaded. So Class.
forName takes under a millisecond if the class you
have want is already loaded, If not, it might take 15 milliseconds or so to load
it. You pay this time penalty only the first time you use the class. Class.
forName is still slower than hard coding the name
of the class into your code. With hard coding, you avoid repeated HashMap
lookups.
Creating Class Objects
You can’t instantiate Class objects, but most the Class
methods are instance methods, not static. So how do you get a Class
object:
classForName is oblivious to any import statements,
so you must fully qualify your class names.
The .class syntax is a kludge, especially double.class.
It behaves as though it were a read-only static
field even though there is no such field, though obviously there must a hidden
pointer in the Class object to the class name.
Class Instance Methods
You can then use methods like Class.toString, Class.getName,
Class.getLoader and Class.getSuperclass
to tell you even more about the class.
Once you have the class, you can then play games with java.lang.reflect.*.
Given just the class object, you can find out the constructors, methods,
parameters to those methods and the members.
You can also dynamically construct new objects whose implementing code did not
even exist at compile time and call methods on those objects.
To keep thing simple, when you have variable classes, they all implement some
interface, abstract class or base class, in this case HolInfo:
To go the other way, to get the class name from an object, use obj.getClass().getName().
For a practical example of the technique,
Holiday Calculator: source also uses Class.forName
Learn To Count: source code to allow you to add new language translators or calculators or classes for new holidays, without modifying or recompiling the program; you just add the class names to a properties file
If the class you are looking for is on the classpath, you can find out which
directory or jar or URL it came from with code like this:
Sometimes the code may not even have a location, e.g. it was dynamically
generated on the fly, either by generating Java source and compiling it with the
internal compiling class (sun.tools.javac.
Main or generating byte codes on the fly (JASM).
Warning
Don’t go frivolously using classForName since it
will allocate the statics and load all the methods
for that class.
Learning More
Sun’s Javadoc on the
Class class : available: