首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Java ClassLoader学习2:ClassLader源码

2013-12-02 
Java ClassLoader学习二:ClassLader源码????? SecureClassLoader:这个类我没做深入研究,你把它当成一个增

Java ClassLoader学习二:ClassLader源码

????? SecureClassLoader:这个类我没做深入研究,你把它当成一个增强版的ClassLoader,增强了从何地load class,增强了能不能load这些代码权限。

?

public abstract class ClassLoader {// 父ClassLoaderprivate ClassLoader parent;// 被此classLoader加载过的Class对象private Vector classes = new Vector();// The packages defined in this class loader. Each package name is mapped // to its corresponding Package object. private HashMap packages = new HashMap();// 由虚拟机调用void addClass(Class c) {classes.addElement(c);}// The packages defined in this class loader. Each package name is mapped// to its corresponding Package object.private final HashMap<String, Package> packages = new HashMap<String, Package>();// 指明parentprotected ClassLoader(ClassLoader parent) {this(checkCreateClassLoader(), parent);}// 不指名parent时使用SystemClassLoaderprotected ClassLoader() {this(checkCreateClassLoader(), getSystemClassLoader());}// 默认resolve=falsepublic Class<?> loadClass(String name) throws ClassNotFoundException {return loadClass(name, false);}protected synchronized Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException {// 1 检查此class是否被此classloader加载过,// 最终是有native方法返回,native方法会使用到classes集合Class c = findLoadedClass(name);// 1.1 未被加载if (c == null) {try {// 1.1.1 此classloader有parent,委托parent去loadif (parent != null) {c = parent.loadClass(name, false);} else {// 1.1.2 此classloader无parent = 启动类装载器去加载c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {}// 如果没有找到class,自己去加载试试if (c == null) {c = findClass(name);}}// 找到的Class对象是否需要连接操作if (resolve) {resolveClass(c);}// 1.2 被加载过,直接返回return c;}protected final Class<?> findLoadedClass(String name) {if (!checkName(name))return null;return findLoadedClass0(name);}// 如果name里包含/,或者虚拟机不支持class数组你使用了数组的时候返回false,其它情况返回true,包括空的name// eg com.jyz.component.core.collection.Tuple return trueprivate boolean checkName(String name) {if ((name == null) || (name.length() == 0))return true;if ((name.indexOf('/') != -1)|| (!VM.allowArraySyntax() && (name.charAt(0) == '[')))return false;return true;}// 检查package是否可访问private void checkPackageAccess(Class cls, ProtectionDomain pd) {final SecurityManager sm = System.getSecurityManager();if (sm != null) {// ...}domains.add(pd);}// 自定义classloader时重写此方法protected Class<?> findClass(String name) throws ClassNotFoundException {throw new ClassNotFoundException(name);}// 将byte数组转换成一个Class对象,最终有native方法实现// 同一个byte数组,被不同的classloader加载,产生两个不同的Class对象protected final Class<?> defineClass(String name, byte[] b, int off, int len)throws ClassFormatError {return defineClass(name, b, off, len, null);}/* * Determine protection domain, and check that: - not define java.* class, - * signer of this class matches signers for the rest of the classes in * package. *///native的defineClass时会调用此方法检查name是否合法//首先checkName,然后还需要!name.startsWith("java.")//所以我们定义了java.mypackage包,都将异常//java.lang.SecurityException: Prohibited package name: java.mypackageprivate ProtectionDomain preDefineClass(String name,ProtectionDomain protectionDomain) {if (!checkName(name))throw new NoClassDefFoundError("IllegalName: " + name);if ((name != null) && name.startsWith("java.")) {throw new SecurityException("Prohibited package name: "+ name.substring(0, name.lastIndexOf('.')));}//...}// protected的resolveClass方法,可以在自定义的classloader调用protected final void resolveClass(Class<?> c) {resolveClass0(c);}//获得appClassLoader,实际调用Launcher完成public static ClassLoader getSystemClassLoader() {sun.misc.Launcher l = sun.misc.Launcher.getLauncher();return l.getClassLoader(); }}

?

?

三.源码说明?

    ?loadClass这个类是重点。
        检查此class是否被此classloader加载过,有直接返回此class检查此ClassLoader有无parent,有委托parent去load。无说明此CassLoader为ExtClassLoader,交给BootstrapLoader去加载。其实可以说委托parent去加载某个ClassLoaer的parent并未加载到指定class,自己findClass(String name)去加载。最后判断找到的Class对象是否需要连接操作并执行。
    自定义classloader时重写findClass(String name)。ClassLoader.etSystemClassLoader()实际由sun.misc.Launcher去完成。ClassLoader构造函数里,不指名parent的话使用AppClassLoader。

?

?

热点排行