classload

这是一篇关于classload的文章,原理和源码解析。

class的查找和加载方式:

双亲代理模型

指的是子类加载器在加载一个目标类的时候,在没有加载过的情况下,先通过委托父类加载器去加载目标类的,只有父类加载器加载失败的时候,才从自己这里加载。这是一个递归的过程,从下层一直到上层。
java.lang.ClassLoad类的loadClass()方法上可以看出这个逻辑:

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;
}

优 势:
1、一个类如果被上层的ClassLoader加载了,那它拥有了更长的生命周期。以此可推,一个类如果被根部的ClassLoader加载过,那在以后整个系统的生命周期内,这个类永远不会被重新加载,具有了共享的功能,在任何地方用到都不用重新加载。
2、安全保护的作用,即使是包名一样的类,只要加载ClassLoader不同,那么它们就是不相等的。这样可以限制用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。

安卓的ClassLoader模型

  • java.lang.ClassLoader
  • java.lang.BootClassLoader:应该是系统才会用到的类,集成了ClassLoader,在ClassLoader调用链的最前面。
  • dalvik.system.BaseDexClassLoader:基类
  • dalvik.system.DexClassLoader:继承BaseDexClassLoader的loader类,可以加载文件系统上的jar、dex、apk。
  • dalvik.system.PathClassLoader:继承BaseDexClassLoader的loader类,可以加载文件系统上的jar、dex、apk。
    • DexClassLoader和PathClassLoader在作用上其实是差不多的,唯一的差别是PathClassLoader传入了optimizedDirectory(directory where optimized dex files should be written)。
  • dalvik.system.DexPathList:实际的ClassLoader的操作者,
  • dalvik.system.DexFile:用来保存dex文件,DexPathList需要使用它。

android类的加载过程:
调用ClassLoader的loadClass(),由于BaseDexClassLoader重写了findClass()方法,所以走到BaseDexClassLoader的里面,而BaseDexClassLoader里是调用了DexPathList的findClass,而findClass就是遍历了所有加载过的dex文件,最总走到DexFile的loadClassBinaryName方法。

自定义ClassLoader

findClass方法:这是自定义class loader类必须覆盖的方法,用于告诉class loader到哪里去加载类,比如某个目录或者JAR URL等。

其他方法可不一定要实现。

延伸阅读

  • 类的实例化分两个过程:类的加载类的实例化。而类的加载又分为显示加载隐式加载
    • 隐式加载就是new创建
    • 显示加载是ClassLoader
  • java类加载器层次结构:
    • BootStrapClassLoader: 负责 sun.boot.class.path 路径下类的加载,默认为 jre/lib 目录下的核心 API 或 -Xbootclasspath 选项指定的 jar包。
    • ExtClassLoader:加载路径为 java.ext.dirs,默认为 jre/lib/ext 目录或者 -Djava.ext.dirs 指定目录下的 jar 包加载。
    • AppClassLoader:加载路径为 java.class.path,默认为环境变量 CLASSPATH 中设定的值。也可以通过 -classpath 选型进行指定。
    • CustomClassLoader:根据用户的需要定制自己的类加载过程,在运行期进行指定类的动态实时加载

Android平台的ClassLoader

http://www.jianshu.com/p/a620e368389a

results matching ""

    No results matching ""