class loader学习

 

1 类加载的责任链模式

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance.

 

执行过程jdk7

 

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

使用双亲委派的方式目的是为了安全性和避免重复,例如可以防止用户自定义的java.lang.String类覆盖jdk内置的String类,对系统造成破坏。

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html

 

2 类加载器体系结构

Bootstrap ClassLoader/启动类加载器 
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。是类加载器树的根节点。

Extension ClassLoader/扩展类加载器 
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。

System ClassLoader(AppClassLoader)/系统类加载器 
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。

以上3个都是jvm的内建实现。

 

User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类) 
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。

http://blog.chenlb.com/2009/06/java-classloader-architecture.html

http://boy00fly.iteye.com/blog/1096912

 

默认情况下,jvm会启动Bootstrap\Extension 类加载器加载jdk的核心类,然后app类加载器再去加载classpath(包括操作系统环境变量中)中的类。

除了文件系统,class还有可能来自网络的。可以通过java.lang.ClassLoader.defineClass(String name, byte[] b, int off, int len)方式定义,再由Class.newInstance()实例化。

 

3 自定义类加载器

用于支持动态类加载,也是java安全的一种手段。不同的类加载器产生不同的命名空间,不同命名空间中的类默认不可相互访问。防止不可信任的代码恶意修改、破坏另一个类加载器中的正常代码。

 

你可能感兴趣的:(java,类加载器)