美文网首页
### jvm的类加载机制-类加载器和双亲委派机制(二)

### jvm的类加载机制-类加载器和双亲委派机制(二)

作者: 行人墨客 | 来源:发表于2017-09-27 00:50 被阅读0次

    类与类加载器


    对于任何一个类,都需要有加载它的类加载器和这个类本身一通确立其在java虚拟机中的唯一性。每一个类加载器,都需要有一个独立的类名称空间。
    更通俗一点的意思是:如果需要比较两个类是否 相等,只有当这两个类都是同一个类加载器加载的前提下,才能进行比较,否则如果加载这两个类的加载器完全不同,则这两个类必定是不一样的。

    package com.deem.classload.test;
    
    import java.io.InputStream;
    
    public class ClassLoadTest {
    
        public static void main(String[] args) throws Exception {
            ClassLoader myClassLoad = new ClassLoader() {
                @Override
                public Class<?> loadClass(String name) throws ClassNotFoundException {
    
                    try {
                        String className = name.substring(name.lastIndexOf(".") + 1) + ".class";
                        InputStream is = getClass().getResourceAsStream(className);
                        if (is == null) {
                            return super.loadClass(name);
                        }
                        byte[] b = new byte[is.available()];
                        is.read(b);
                        return defineClass(name, b, 0, b.length);
    
                    } catch (Exception e) {
                        throw new ClassNotFoundException(name);
                    }
                }
            };
    
            Object obj = myClassLoad.loadClass("com.deem.classload.test.ClassLoadTest").newInstance();
    
            System.out.println(obj.getClass());
            System.out.println(obj instanceof com.deem.classload.test.ClassLoadTest );
        }
    
    }
    
    运行结果为

    class com.deem.classload.test.ClassLoadTest
    false

    从第一个输出结果来看,这个对象确实是类com.deem.classload.test.ClassLoadTest实例化出来的对象
    第二句 最比较时,返回 false,这个对象时通过我们自定义的类加载器进行加载的,其实此时虚拟机中存在了两个ClassLoadTest类,一个是系统应用程序自己加载的,另一个则是我们自己定义的类加载器进行加载的,虽然都是同一个Class文件,但是依然是两个独立的类,故而结果是false

    类加载器与双亲委派机制


    JVM预定义的三种类型类加载器:
    1. 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。
    1. 标准扩展(Extension)类加载器:是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将< Java_Runtime_Home >/lib/ext或者由系统变量 java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。
    1. 系统(System)类加载器:是由 Sun 的
      AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用系统类加载器。

    除了以上列举的三种类加载器,还有一种比较特殊的类型 — 线程上下文类加载器。

    双亲委派机制描述
    image.png image.png

    某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

    参考
    1. 周志明,深入理解Java虚拟机:JVM高级特性与最佳实践,机械工业出版社
    2. Alexia(minmin)博客,http://www.cnblogs.com/lanxuezaipiao/p/4138511.html
    3. 笨鸟快飞的博客,http://blog.csdn.net/u011080472/article/details/51332866

    相关文章

      网友评论

          本文标题:### jvm的类加载机制-类加载器和双亲委派机制(二)

          本文链接:https://www.haomeiwen.com/subject/btkyextx.html