一尘不染

Java ClassLoader委托模型?

java

调用loadClass()ClassLoaderClassLoader首先检查该类是否已加载,还是立即将该检查委托给其父级ClassLoader

Java API说:

当请求查找类或资源时,ClassLoader实例会将对类或资源的搜索委托给其父类加载器,然后再尝试查找类或资源本身。

但是在《 Java Reflection in Action》 一书中有一章关于类加载器的特定章节说:

类加载器调用findLoadedClass来检查该类是否已经加载。如果类加载器找不到加载的类,请在父类加载器上调用loadClass。

哪个是正确的?


阅读 157

收藏
2020-12-03

共1个答案

一尘不染

正确的类加载器实现将:

  1. 检查该类是否已经加载。
  2. 通常要求父类加载器加载该类
  3. 尝试在自己的班级路径中查找班级。

ClassLoader.loadClass的默认实现是这样的:

protected synchronized Class<?> loadClass(String name, boolean resolve) {
  // First, check if this class loader has directly defined the class or if the
  // JVM has initiated the class load with this class loader.
  Class<?> result = findLoadedClass(name);
  if (result == null) {
    try {
      // Next, delegate to the parent.
      result = getParent().loadClass(name);
    } catch (ClassNotFoundException ex) {
      // Finally, search locally if the parent could not find the class.
      result = findClass(ex);
    }
  }
  // As a remnant of J2SE 1.0.2, link the class if a subclass of the class
  // loader class requested it (the JVM never calls the method,
  // loadClass(String) passes false, and the protected access modifier prevents
  // callers from passing true).
  if (resolve) {
    resolveClass(result);
  }
  return result;
}

一些类加载器实现将委派给其他非父类加载器(例如,OSGi,取决于包,委派给类加载器的图),而某些类加载器实现会在委派之前在本地类路径中查找类。

2020-12-03