在装入类的父级委托模型中,我知道loadclass()是在父级上调用的,一直到类装入器层次结构的顶层(假设类没有装入)。此时调用最上面的父类加载器的findClass。如果找不到这个类,如何将控制转移到下一个类加载器的findClass方法?
发布于 2010-08-23 12:10:13
类加载器的loadClass(String)方法将调用findClass(String)。它的默认实现抛出一个ClassNotFoundException,并打算被类加载器覆盖。
loadClass(String)方法将按该顺序调用以下方法
类加载器首先尝试查找类是否已加载:findLoadedClass(String)
loadClass(String)方法。findClass(String)方法(自定义加载)因此,自定义类加载器所要做的就是覆盖findClass(String)方法,以自定义方式加载类。这将确保在类加载中进行适当的委托。查看链接(javadoc),它解释了采取了哪些步骤以及如何从loadClass(String)调用findClass(String)
因此,类加载按以下顺序进行(示例):ClassLoader A与父B(仅解释findClass和loadClass)
A.loadClass()
|
(not-found?) (by findLoadedClass)
|
B.loadClass()
|
(not found?) (by findLoadedClass)
|
systemclassloader.loadClass() (Bs parent, also can be
| called classpath classloader)
|
(not found?) (by findLoadedClass)
|
bootstrap classloader.loadClass() (the bootstrap classloader,
| this has no parent)
|
(not found?)
|
systemclassloader.findClass() (on system classloader,
| will try to "find" class in "classpath")
|
(not found?)
|
B.findClass()
|
(not found?)
|
A.findClass()
|
(not found?)
|
ClassNotFoundException在任何给定的时间,如果找到了类(例如findClass或findLoadedClass),就会返回该类。
发布于 2012-11-08 14:09:34
上面的解释是全面和出色的。要理解委托类加载的原理,更直接的方法是阅读源代码。无论如何,源代码一点也不复杂。
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/lang/ClassLoader.java#400
400 protected Class<?> loadClass(String name, boolean resolve)
401 throws ClassNotFoundException
402 {
403 synchronized (getClassLoadingLock(name)) {
404 // First, check if the class has already been loaded
405 Class c = findLoadedClass(name);
406 if (c == null) {
407 long t0 = System.nanoTime();
408 try {
409 if (parent != null) {
410 c = parent.loadClass(name, false);
411 } else {
412 c = findBootstrapClassOrNull(name);
413 }
414 } catch (ClassNotFoundException e) {
415 // ClassNotFoundException thrown if class not found
416 // from the non-null parent class loader
417 }
418
419 if (c == null) {
420 // If still not found, then invoke findClass in order
421 // to find the class.
422 long t1 = System.nanoTime();
423 c = findClass(name);
424
425 // this is the defining class loader; record the stats
426 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
427 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
428 sun.misc.PerfCounter.getFindClasses().increment();
429 }
430 }
431 if (resolve) {
432 resolveClass(c);
433 }
434 return c;
435 }
436 }https://stackoverflow.com/questions/3544614
复制相似问题