Reputation: 5271
I have seen several places that "Class.getClassLoader() returns the ClassLoader used to load that particular class", and therefore, I am stumped by the results of the following example:
package test;
import java.lang.*;
public class ClassLoaders {
public static void main(String[] args) throws java.lang.ClassNotFoundException{
MyClassLoader mcl = new MyClassLoader();
Class clazz = mcl.loadClass("test.FooBar");
System.out.println(clazz.getClassLoader() == mcl); // prints false
System.out.println(clazz.getClassLoader()); // prints e.g. sun.misc.Launcher$AppClassLoader@553f5d07
}
}
class FooBar { }
class MyClassLoader extends ClassLoader { }
Shouldn't the statement clazz.getClassLoader() == mcl return true? Can someone explain what I am missing here?
Thanks.
Upvotes: 10
Views: 1455
Reputation: 51331
If the selfdefined classloader delegates the call to classloader of the VM, who loads the class. clazz.getClassLoader() will return this classloader.
To get into the detail: The Javadoc of the class ClassLoader provides the following explanation of the order of executed steps:
Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order:
- Invoke findLoadedClass(String) to check if the class has already been loaded.
- Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead.
- Invoke the findClass(String) method to find the class.
As you inherited without a change the methods, this behaviour will be unchanged. Step 2 will be the one, where the class will be loaded. As you call the parameterless constructor of ClassLoader (automatically, as you didn't defined a constructor in MyClassLoader) you automatically make use of the builtin ClassLoader.
Upvotes: -2
Reputation: 346476
Citing the API doc of ClassLoader:
Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.
Upvotes: 6
Reputation: 18894
Whenever you create your own classloader it will be attached in a tree-like hierarchy of classloaders. To load a class a classloader first delegates the loading to its parent. Only once all the parents didn't find the class the loader that was first asked to load a class will try to load it.
In your specific case the loading is delegated to the parent classloader. Although you ask you MyClassLoader to load it, it is the parent that does the loading. In this case it is the AppClassLoader.
Upvotes: 17