Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class.forName() vs ClassLoader.loadClass() - which to use for dynamic loading? [duplicate]

When dynamically loading a class, when is it appropriate to use

Class.forName("SomeClass"); 

and when should I use

ClassLoader.getSystemClassLoader().loadClass("SomeClass"); 

Or, are they two ways of doing the same thing?

like image 808
Zack Avatar asked Nov 11 '11 21:11

Zack


People also ask

When would you use a ClassLoader?

Java ClassLoader is used to load the classes at run time. In other words, JVM performs the linking process at runtime. Classes are loaded into the JVM according to need. If a loaded class depends on another class, that class is loaded as well.

What is purpose of class forName () method?

forName. Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName ) this method attempts to locate, load, and link the class or interface.

Can we load the same class by two ClassLoader?

So when a class is loaded into JVM, you have an entry as (package, classname, classloader). Therefore the same class can be loaded twice by two different ClassLoader instances.

Which ClassLoader loads the files from JDK directory?

Extension ClassLoader: The Extension ClassLoader is a child of Bootstrap ClassLoader and loads the extensions of core java classes from the respective JDK Extension library. It loads files from jre/lib/ext directory or any other directory pointed by the system property java.


1 Answers

They are quite different!

As stated in the documentation for Class.forName(String),

Returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to: Class.forName(className, true, currentLoader)

(true here refers to do you want to initialize the class?)

On the other hand, ClassLoader.loadClass(String):

Invoking this method is equivalent to invoking loadClass(name, false).

(here, the boolean has nothing to do with initialization; but if you check loadClass(String, boolean) documentation, you will see that all it does is load the class, not initialize it).

The first one (Class.forName("SomeClass");) will:

  • use the class loader that loaded the class which calls this code
  • initialize the class (that is, all static initializers will be run)

The other (ClassLoader.getSystemClassLoader().loadClass("SomeClass");) will:

  • use the "system" class loader (which is overridable)
  • not initialize the class (say, if you use it to load a JDBC driver, it won't get registered, and you won't be able to use JDBC!)

Suppose you are coding a web application that will be executed on a container such as Tomcat. What Tomcat does is create a class loader for each web application (so that it can unload the webapps later and release memory -- you need a dedicated class loader for this to work!). In this situation, you can see that both calls will yield quite different results!

For more detailed (and authoritative) information on class loading and initialization, check sections 12.2 and 12.4 of the latest (3rd) edition of the Java Language Specification.

like image 61
Bruno Reis Avatar answered Oct 06 '22 20:10

Bruno Reis