美文网首页
类的加载(doing)

类的加载(doing)

作者: Wi1ls努力努力再努力 | 来源:发表于2018-12-12 11:58 被阅读0次

双亲委派模型

loadClass(String,boolean)@ClassLoader

protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException{
  Class<?> clazz = findLoadedClass(className);//⑴
  
  if (clazz == null){
    ClassNotFoundException suppressed = null;
    try{
      clazz = parent.loadClass(className, false);  //⑵
    }catch(ClassNotFoundException e){
      suppressed = e;
    }

    if(clazz == null){
      try{
        clazz = findClass(className);⑶
      }catch(ClassNotFoundException e){
        e.addSuppressed(suppressed);
        throw e;
      }
    }
  }
  return clazz;
}

-⑴查找本加载器是否已经加载过这个 class

  • 若没有
    -⑵优先请求父类加载
    • 若父类未加载过且加载失败
      • ⑶本加载器进行加载

ClassLoader.java

protected ClassLoader(){
  this(getSystemClassLoader(), false);
}

protected ClassLoader(ClassLoader parentLoader){
  this(parentLoader, false);
}

ClassLoader(ClassLoader parentLoader, boolean nullAllowed){
  if(parentLoader == null && !nullAllowed){
      threow new NullPointerException("parentLoader == null && !nullAllowed);
  }
  parent = parentLoader;
}

pubic static ClassLoader getSystemClassLoader(){
  return SystemClassLoader.loader;
}

static private class SystemClassLoader{
  public static ClassLoader loader = ClassLoader.createSystemClassLoader();
}

private static ClassLoader createSystemClassLoader(){
  String classPath = System.getProperty("java.class.path",".");
   
  return new PathClassLoader(classPath,BootClassLoader.getInstance());
}
  • 当 CustomClassLoader 时,不指明其 parentLoader,默认parent 为 PathClassLoader,同时 PathClassLoader 的 parentLoader 是 BootClassLoader。同事也可以看出,PathClassLoader 加载System.getProperty("java.class.path",".")下的 dex 相关;

PathClassLoader 和 DexClassLoader 继承自 BaseDexClassLoader,其主要逻辑都在 BaseDexClassLoader,不同点在于构造函数传入的参数。

DexClassLoader

public DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent){
  super(dexPath, new File(optimizedDirectory), libraryPath, parent);
}

PathClassLoader

public PathClassLoader(String dexPath, ClassLoader parent){
  super(dexPath, null, null, parent);
}

public PathClassLoader(String dexPath, String libraryPath, ClassLoader parent){
  super(dexPath, null, library, parent);
}

BaseDexClassLoader

/**
     * Constructs an instance.
     *
     * @param dexPath the list of jar/apk files containing classes and
     * resources, delimited by {@code File.pathSeparator}, which
     * defaults to {@code ":"} on Android
     * @param optimizedDirectory directory where optimized dex files
     * should be written; may be {@code null}
     * @param libraryPath the list of directories containing native
     * libraries, delimited by {@code File.pathSeparator}; may be
     * {@code null}
     * @param parent the parent class loader
     */
public BaseDexClassLoader(String dexPath, File optimizedDirectory, String libraryPath, ClassLoader parent){
    super(parent);
    this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
}
  • 参数介绍
    • dexPath:dex 相关文件路径集合,多路径用文件分隔符分割,默认“:”
    • optimizedDirectory:解压的 dex 文件存储路径,必须是内部存储路径。一般情况下使用/data/data/<Package Name>/...
    • librarySerchPath:包含 c/c++库路径,多路径分割,可为 null
    • parent:父加载器

findClass(String)@BaseDexClassLoader.java

protected Class<?> findClass(String name) throws ClassNotFoundException{
  List<Throwable> suppressedExceptions = new ArrayList<Throwable>( );
  Class c = pathList.findClass(name, suppressedExceptions);
  return c;
}

上述的 pathList 在构造函数中实例化,是 DexPathList 对象

DexPathList

public DexPathList(ClassLoader definingContext, String dexPath, String libraryPath, File optimizedDirectory){
  ...
  this.definingContext = definingContext;
  this.dexElements = makePathElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions);
  this.nativeLibraryDirectories = splitPaths(libraryPath, false);
  this.systemNativeLibraryDirectories = splitPaths(System.getProperty("java.library.path"), true);
  this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null, suppressedExctprions);
}

public Class findClass(String name, List<Throwable> suppressed){
  for(Element element : dexElements){
    DexFile dex = element.dexFile;

    Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
    return clazz;
  }
}

DexFile.java

public Class loadClassBinaryName(String name, ClassLoader loader, List<Throwable> suppressed){
  return defineClass(name, loader, mCookie, suppressed);
}

private static Class defineClass(String name, ClassLoader loader, Object cookie, List<Throwable> suppressed){
  Class result = defineClassNamtive(name, loader, cookie);
}

相关文章

  • 类的加载(doing)

    双亲委派模型 loadClass(String,boolean)@ClassLoader -⑴查找本加载器是否已经...

  • 第一章 类加载过程

    要点 类加载过程 类加载器 一、类加载过程 1.类的加载过程 类的加载 .class文件过程分为:加载---->连...

  • 深入理解jvm类加载机制

    1.什么是类加载? 类加载机制一个很大的体系,包括类加载的时机,类加载器,类加载时机。 1.1类加载过程 加载器加...

  • java基础知识之java类加载器

    1. 什么是类加载器 类加载器就是用来加载类的东西!类加载器也是一个类:ClassLoader 类加载器可以被加载...

  • 《深入理解JVM虚拟机》读书笔记-类加载器&Java模块化系统

    类加载器 一.类加载器 1.1 类与类加载器 类加载器的定义: Java虚拟机设计团队有意把 类加载阶段中 的“ ...

  • JVM类加载入门

    一 类加载顺序 class类加载-->验证-->准备--->解析--->初始化 class类加载:通过类加载器加载...

  • 学习笔记 | JAVA的反射(二)

    利用反射机制动态加载类 、获取类的方法、获取类的属性 编译时刻加载类是静态加载类,运行时加载类是动态加载类 正常创...

  • jvm类加载器详解和如何打破双亲委派机制

    类加载过程: 项目启动的时候,并不是加载项目中的所有类,是在使用的时候加载,类加载器加载类的时候首先加载父类,所以...

  • JVM - ClassLoader

    1. 概述 类加载器实际定义了类的namespace。 2.类加载方式之当前类加载器和指定类加载器 类的加载只有两...

  • java-类加载机制

    类的加载机制 主要关注点: 什么是类的加载 类的生命周期 类加载器 双亲委派模型 什么是类的加载 类的加载指的是将...

网友评论

      本文标题:类的加载(doing)

      本文链接:https://www.haomeiwen.com/subject/cbeuhqtx.html