Launcher类解析--系统类加载器

sun.misc.Launcher类,类中定义了几个类加载器。

AppClassLoader 系统类加载器
ExtClassLoader 扩展类加载器
关于类加载器的一些东西,可以看这篇类加载

Launcher的getClassPath(String classPath):

private static File[] getClassPath(String classPath) {
        File[] classFiles;
        if(classPath != null) {

            int fileCount = 1;

            int var5; //移动游标
            int separatorIndex; // ;符号的位置
            for(var5 = 0; (separatorIndex = classPath.indexOf(File.pathSeparator, var5)) != -1; var5 = separatorIndex + 1) {
                ++fileCount;
            }

            classFiles = new File[fileCount];
            int var2 = 0;
            for(var5 = 0; (separatorIndex = classPath.indexOf(File.pathSeparator, var5)) != -1; var5 = separatorIndex + 1) {
                if(separatorIndex - var5 > 0) {
                    classFiles[var2++] = new File(classPath.substring(var5, separatorIndex));
                } else {
                    classFiles[var2++] = new File(".");
                }
            }

            if(var5 < classPath.length()) {//classPath,不是以分号结尾时,把分号后面的作为一个文件路径放入数组
                classFiles[var2++] = new File(classPath.substring(var5));
            } else {
                classFiles[var2++] = new File(".");
            }

            if(var2 != fileCount) {//以var2为准,如果 原始数组没填满,则复制到新数组中。
                File[] var6 = new File[var2];
                System.arraycopy(classFiles, 0, var6, 0, var2);
                classFiles = var6;
            }
        } else {
            classFiles = new File[0];
        }

        return classFiles;
    }

AppClassLoader类:

/**
* var1  类全名
* var2 是否连接该类
*/
public Class loadClass(String var1, boolean var2) throws ClassNotFoundException {
            int var3 = var1.lastIndexOf(46);
            if(var3 != -1) {
                SecurityManager var4 = System.getSecurityManager();
                if(var4 != null) {
                    var4.checkPackageAccess(var1.substring(0, var3));
                }
            }

            if(this.ucp.knownToNotExist(var1)) {//一般都是false,想要返回TRUE可能需要设置启动参数lookupCacheEnabled 为true。为true时,具体的逻辑也是C++写的,所以做了什么就不大清楚了。
                Class var5 = this.findLoadedClass(var1); //如果这个类已经被这个类加载器加载,则返回这个类,否则返回Null
                if(var5 != null) {
                    if(var2) {
                        this.resolveClass(var5); //如果该类没有被link(连接),则连接,否则什么都不做
                    }

                    return var5;
                } else {
                    throw new ClassNotFoundException(var1);
                }
            } else {
                return super.loadClass(var1, var2);
            }
        }
protected Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);//委托父加载器加载
                    } else {
                        c = findBootstrapClassOrNull(name);//没有父加载器了,说明是启动类加载器,则委托启动类加载器加载
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {//父加载器加载失败,则由自己加载。
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);//加载这个类的总耗时
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);//记录这个类的逃逸时间起点
                    sun.misc.PerfCounter.getFindClasses().increment();//记录总共加载的类的个数
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
 protected Class findClass(final String name)
        throws ClassNotFoundException
    {
        final Class result;
        try {
            result = AccessController.doPrivileged(
                new PrivilegedExceptionAction>() {
                    public Class run() throws ClassNotFoundException {
                        String path = name.replace('.', '/').concat(".class");
                        Resource res = ucp.getResource(path, false);
                        if (res != null) {
                            try {
                                return defineClass(name, res);
                            } catch (IOException e) {
                                throw new ClassNotFoundException(name, e);
                            }
                        } else {
                            return null;
                        }
                    }
                }, acc);
        } catch (java.security.PrivilegedActionException pae) {
            throw (ClassNotFoundException) pae.getException();
        }
        if (result == null) {
            throw new ClassNotFoundException(name);
        }
        return result;
    }

扩展类加载器,并没有覆盖Loadclass方法,只是定义了一些加载路径,再考虑到一般它由jvm控制调用,所以也就不深究了。

你可能感兴趣的:(java基础)