安卓类加载机制和双亲委派机制

类加载机制

在安卓中提供了3个类加载器,BootClassLoader,PathClassLoader,DexClassLoader;双亲委派机制,是委培层级上的上下层级关系,并不是说3个类加载器有父子继承关系:

类加载的委派层级

BootClassLoader -> PathClassLoader -> DexClassLoader ;

类加载器的继承结构

BootClassLoader 是父类 , PathClassLoader / DexClassLoader 是 BootClassLoader 的子类 ;

① DexClassLoader 查询 :查询自己是否加载过 A ;

如果加载过则不需要再进行加载 ;

如果没有加载过 , 则向上级 PathClassLoader 询问 是否有加载过 A ;

② PathClassLoader 查询 :查询自己是否加载过 A ;

如果加载过则不需要再进行加载 ;

如果没有加载过 , 则向上级 BootClassLoader 询问 是否有加载过 A ;

③ BootClassLoader 查询 :查询自己是否加载过 A ;

如果加载过则不需要再进行加载 ;

如果没有加载过 , 则 查询自己是否可以加载 ;

④ BootClassLoader 查询是否可以加载 :

如果自己可以加载 A , 则自己加载 ;

如果自己不可以加载 A , 则将加载任务委派给下级 PathClassLoader ;

⑤ PathClassLoader 查询是否可以加载 :

如果自己可以加载 A , 则自己加载 ;

如果自己不可以加载 A , 则将加载任务 委派给下级 DexClassLoader ;

④ DexClassLoader 查询是否可以加载 :

如果自己可以加载 A , 则自己加载 ;

如果自己不可以加载 A , 则 抛出 Class Not Found 异常 ;

整个过程就是 从下到上 询问 , 然后 从上到下 委派 ;

双亲委派机制

类加载器层级

由高到低 : BootClassLoader -> PathClassLoader / DexClassLoader

什么是双亲委派

1.加载.class文件的时候,以递归的的形式逐级向上委托给父加载器ParentClassLoader去加载,如果加载过了,就不用在加载一遍2.如果父加载器也没加载过,则继续委托给父加载器去加载,一直到这条链路的顶级,顶级classLoader判断如果没加载过,则尝试加载,加载失败,则逐级向下交还调用者来加载.

双亲委派是如何实现的

任意一个classLoader对象都会有一个parent对象,我们下面的customClassLoader创建的时候虽然没有传递parent对象,但是在下面的ClassLoader类中的空参构造方法可以看出,会调用getSystemClassLoader()从而调用ClassLoader.createSystemClassLoader();,最后创建了一个PathClassLoader对象作为parent,而且在创建PathClassLoader的同时也指定了它的parent为BootClassLoader

ClassLoader customClassLoader= new ClassLoader() {

            @Override

            public Class<?> loadClass(String name) throws ClassNotFoundException {

                return super.loadClass(name);

            }

  };

public abstract class ClassLoader {

    static private class SystemClassLoader {

        public static ClassLoader loader = ClassLoader.createSystemClassLoader();

    }

    protected ClassLoader() {

        this(checkCreateClassLoader(), getSystemClassLoader());

    }

    protected ClassLoader(ClassLoader parent) {

        this(checkCreateClassLoader(), parent);

    }

    @CallerSensitive

    public static ClassLoader getSystemClassLoader() {

        return SystemClassLoader.loader;

    }

    private static ClassLoader createSystemClassLoader() {

        String classPath = System.getProperty("java.class.path", ".");

        String librarySearchPath = System.getProperty("java.library.path", "");

        //最终会调用PathClassLoader这个classLoader

        return new PathClassLoader(classPath, librarySearchPath, BootClassLoader.getInstance());

    }

    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{

            //1.先检查是否已经加载过--findLoaded

            Class<?> c = findLoadedClass(name);

            if (c == null) {

                try {

                    //2.如果自己没加载过,存在父类,则委托父类

                    if (parent != null) {

                        c = parent.loadClass(name, false);

                    } else {

                        c = findBootstrapClassOrNull(name);

                    }

                } catch (ClassNotFoundException e) {

                }

                if (c == null) {

                    //3.如果父类也没加载过,则尝试本级classLoader加载

                    c = findClass(name);

                }

            }

          return c;

    }

}

loadClass方法,对于任意一个classLoader对象来说,来加载文件的时候都会调用loadClass方法.

1.先检查自己是否已经加载过class文件了--用这个findLoadedClass方法,如果已经加载了直接返回就好了2.如果自己没加载过,存在父类,则委托父类去加载--用这个parent.loadClass(name, false)方法,此时就会向上传递,然后就会去父加载器中循环第1步,一直到顶级ClassLoader3.如果父类也没加载过,则尝试本级classLoader加载,如果加载失败了就会向下传递,交给调用方来实现.class文件的加载

双亲委派的作用

1.防止同一个.class文件重复加载

2.对于任意一个类确保在虚拟机中的唯一性.由加载它的类加载器和这个类的全类名一同确立其在Java虚拟机中的唯一性

3.保证.class文件不被篡改,通过委托方式可以保证系统类的加载逻辑不被篡改.

Android中的主要类加载器

1.PathClassLoader复杂的加载系统类和英勇程序的类,通常用来加载已安装apk的dex文件,实际上外部存储的dex文件也能加载

2.DexClassLoader可以加载dex文件以及包含dex的压缩文件(apk,dex,jar,zip)

3.BaseDexClassLoader实际应用层类文件的加载,而真正的加载逻辑委托给pathList来完成

4.BootClassLoaderAndroid平台上所有ClassLoader的最终parent,Android系统启动时会使用BootClassLoader来预加载常用类


©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容