Java: Difference between Class.forName and ClassLoader.loadClass

Shaun's answer is more or less correct except few omissions/small errors:

  • Class.forName associates the class w/ the ClassLoader (regardless if any other parent loads it for real), hence ClassLoader.findLoadedClass is successful next time. That's a very, very important point, most ClassLoader would try Class c = findLoadedClass(name); if (c!=null) return c; as first statements bypassing the whole find/look up part. Calling ClassLoader.load directly will not add the class to the loaded ones.

The case has implications when loaded via graph alike structure of ClassLoader, i.e. not using parent only to lookup first.

  • Initialization of the class is performed in loadClass of the ClassLoader w/ code like that: if (resolve) resolveClass(c); and the ClassLoader can actually skip resolve it it feels like, unrecommended but possible.

What are the do's and dont's to using these two methods?

Unless you have very strong idea why you want ClassLoader.loadClass(String), do not use it directly. In all other case, always rely on Class.forName(name, true, classLoader).

Overall Class loading is next to an art and it cannot be covered in a simple answer (not joking about art part)


Class.forName() will always use the ClassLoader of the caller, whereas ClassLoader.loadClass() can specify a different ClassLoader. I believe that Class.forName initializes the loaded class as well, whereas the ClassLoader.loadClass() approach doesn't do that right away (it's not initialized until it's used for the first time).

Just found this article when looking to confirm my summary of the initialization behavior. It looks like this has most of the information you're looking for:

http://www.javaworld.com/javaworld/javaqa/2003-03/01-qa-0314-forname.html

This usage is pretty cool, though I've never used it before:

Class.forName(String, boolean, ClassLoader)

It allows you to specify a ClassLoader and the boolean parameter defines whether the class should be initialized when it's loaded or not.