【JVM】类加载器及双亲委派模型

版权声明:原创欢迎转载,转载请注明出处 https://blog.csdn.net/ye17186/article/details/88872672

类加载器

类加载器就是根据指定全限定名称,将class文件加载到JVM内存中,转为Class对象。JAVA中的类加载器有下面这四种:

1、启动类加载器(Bootstrap ClassLoader):负责加载Java的核心库(<JAVA_HOME/lib>)中的类,用原生C++写的,并不集成自java.lang.ClassLoader;

2、扩展类加载器(Extensions ClassLoader):负责加载Java扩展扩库(<JAVA_HOME>/lib/ext)中的类;

3、应用程序类加载器(Application ClassLoader):也叫系统类加载器,它根据应用的类路径(CLASSPATH)来加载类;

4、自定义类加载器(Custom ClassLoader):应用开发人员可以通过继承java.lang.ClassLoader的方式,来实现自己的类加载器,已满足定制化需求。

模型:

测试代码:

public class Test {

    public static void main(String[] args) {

        // System ClassLoader
        System.out.println(ClassLoader.getSystemClassLoader());
        // Extensions ClassLoader
        System.out.println(ClassLoader.getSystemClassLoader().getParent());
        // Bootstrap ClassLoader
        System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());
    }
}

可以清楚看出,测试类Test,是有AppClassLoader加载的,它的父加载器是ExtClassLoader,而ExtClassLoader的父加载器,打印结果为null,是因为Bootstrap ClassLoader是由C++实现的,这里获取不到。

双亲委派模型

如果一个类加载器收到类加载的请求,该加载器不会自己去加载,而且委派给父类加载器去加载,父类加载器收到加载请求后,同样会继续向上委派,直到最顶层的Bootst ClassLoader。如果父加载器可以加载此类,则成功返回,否则会将加载任务回退给子类加载器去加载。

1、为什么要采用双亲委派模型

假设某黑客,自定义了一个类java.lang.String,拥有和JDK自带的String类同样的功能,只不过修改了其中的equals方法,加入了一些病毒代码,并且通过自定义的类加载器,加载到JVM中。如果没有双亲委派模型,JVM可能会误以为黑客的这个“String”类是正确的,程序是使用equals方法时,调用了黑客的String类,执行了其中的病毒代码。另外一个原因就是保证同一个类只会被加载一次,假设两个加载器都收到的加载请求,如果不采用双亲委派,这个类将会被他们分别加载,而在双亲委派模型下,向上委派,加载一次后,不会加载第二次了。

猜你喜欢

转载自blog.csdn.net/ye17186/article/details/88872672