Both methods try to dynamically locate and load ajava.lang.Class
object corresponding to a given class name. However, their behavior differs regarding whichjava.lang.ClassLoader
they use for class loading and whether or not the resultingClass
object is initialized.
The most common form ofClass.forName()
, the one that takes a singleString
parameter, always uses thecaller'sclassloader. This is the classloader that loads the code executing theforName()
method. By comparison,ClassLoader.loadClass()
is an instance method and requires you to select a particular classloader, which may or may not be the loader that loads that calling code. If picking a specific loader to load the class is important to your design, you should useClassLoader.loadClass()
or the three-parameter version offorName()
added in Java 2 Platform, Standard Edition (J2SE):Class.forName(String, boolean, ClassLoader)
.
Additionally,Class.forName()
's common form initializes the loaded class. The visible effect of this is the execution of the class's static initializers as well as byte code corresponding to initialization expressions of all static fields (this process occurs recursively for all the class's superclasses). This differs fromClassLoader.loadClass()
behavior, which delays initialization until the class is used for the first time.
You can take advantage of the above behavioral differences. For example, if you are about to load a class you know has a very costly static initializer, you may choose to go ahead and load it to ensure it is found in the classpath but delay its initialization until the first time you need to make use of a field or method from this particular class.
The three-parameter methodClass.forName(String, boolean, ClassLoader)
is the most general of them all. You can delay initialization by setting the second parameter tofalse
and pick a given classloader using the third parameter. I recommend always using this method for maximum flexibility.
Class initialization errors are tricky
Just because you successfully load a class does not mean there won't be any more problems. Recollect that static initialization code can throw an exception, and it will get wrapped in an instance ofjava.lang.ExceptionInInitializerError
, at which point, the class becomes unusable. Thus, if it is important to process all such errors at a known point in code, you should use aClass.forName()
version that performs initialization.
Furthermore, if you handleExceptionInInitializerError
and take measures so that the initialization can be retried, it will likely not work.