Java界神秘技术ClassLoader,吃透它看这一篇就够了
值得注意的是图中的 ExtensionClassLoader 的 parent 指针画了虚线,这是因为它的 parent 的值是 null,当 parent 字段是 null 时就表示它的父加载器是「根加载器」。如果某个 Class 对象的 classLoader 属性值是 null,那么就表示这个类也是「根加载器」加载的。注意这里的 parent 不是 super 不是父类,只是 ClassLoader 内部的字段。 Class.forName当我们在使用 jdbc 驱动时,经常会使用 Class.forName 方法来动态加载驱动类。
其原理是 mysql 驱动的 Driver 类里有一个静态代码块,它会在 Driver 类被加载的时候执行。这个静态代码块会将 mysql 驱动实例注册到全局的 jdbc 驱动管理器里。
forName 方法同样也是使用调用者 Class 对象的 ClassLoader 来加载目标类。不过 forName 还提供了多参数版本,可以指定使用哪个 ClassLoader 来加载。
通过这种形式的 forName 方法可以突破内置加载器的限制,通过使用自定类加载器允许我们自由加载其它任意来源的类库。根据 ClassLoader 的传递性,目标类库传递引用到的其它类库也将会使用自定义加载器加载。 自定义加载器ClassLoader 里面有三个重要的方法 loadClass()、findClass() 和 defineClass()。 loadClass() 方法是加载目标类的入口,它首先会查找当前 ClassLoader 以及它的双亲里面是否已经加载了目标类,如果没有找到就会让双亲尝试加载,如果双亲都加载不了,就会调用 findClass() 让自定义加载器自己来加载目标类。ClassLoader 的 findClass() 方法是需要子类来覆盖的,不同的加载器将使用不同的逻辑来获取目标类的字节码。拿到这个字节码之后再调用 defineClass() 方法将字节码转换成 Class 对象。下面我使用伪代码表示一下基本过程:
(编辑:惠州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |