Java ClassLoader 委托模型?

2022-09-04 01:13:54

调用 ClassLoader 时,第一个检查是检查类是否已加载,还是立即将此检查委托给其父级?loadClass()ClassLoaderClassLoader

Java API 说:

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

但是在Java Reflection in Action一书中有一章关于类加载器,它说:

类装入器调用 findLoadedClass 来检查是否已装入类。如果类装入器找不到装入的类,那么在父类装入器上调用 loadClass。

哪个是正确的?


答案 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 根据包委托给类装入器图),而某些类装入器实现将在委派之前在本地类路径中查找类。


答案 2

Java API 是正确的。

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

来自 Java 类装入机制 -

装入类时,类装入器首先将类的搜索“委托”给其父类装入器,然后再尝试查找类本身。


推荐