Why is ClassLoader\'s cache checked in ascending sequence while class-loading befalls in descending sequence?
It is purely a matter of efficiency. If you forget about the cache, the order of classloading ensures that Java system classes always take precedence over application classes and that a class can only be loaded by one classloader in a chain. So there is no class that is in more than one cache and so the order of searching the caches makes no functional difference.
In other words, you could search the bootloader cache followed by the extension classloader cache followed by the system classloader cache and then start trying to load the classes and the end result would be exactly the same. To do this would require an extra API to search for a loaded class and would bring little benefit as searching a cache is a very quick operation.
Note that classes can be loaded by more than one classloader, but not if they are in a loader->parent chain.
ClassLoader in Java works on three principle: delegation, visibility and uniqueness. Delegation principle forward request of class loading to parent class loader and only loads the class, if parent is not able to find or load class. Visibility principle allows child class loader to see all the classes loaded by parent ClassLoader, but parent class loader can not see classes loaded by child. Uniqueness principle allows to load a class exactly once, which is basically achieved by delegation and ensures that child ClassLoader doesn't reload the class already loaded by parent.
In other words as described here:
The class loaders in Java are organized in a tree. By request a class loader determines if the class has already been loaded in the past, looking up in its own cache. If the class is present in the cache the CL returns the class, if not, it delegates the request to the parent. If the parent is not set (is Null) or can not load the class and throws a ClassNotFoundException the classloader tries to load the class itself and searches its own path for the class file. If the class can be loaded it is returned, otherwise a ClassNotFoundException is thrown. The cache lookup goes on recursively from child to parent, until the tree root is reached or a class is found in cache. If the root is reached the class loaders try to load the class and unfold the recursion from parent to child. Summarizing that we have following order:
- Cache
- Parent
- Self
This mechanism ensures that classes tending to be loaded by class loaders nearest to the root.