类加载器

来源:互联网 发布:苏州优才通网络怎么样 编辑:程序博客网 时间:2024/06/05 18:25

1、JAVA虚拟机提供了3个类加载器,BootStrap(c++实现,嵌入在jvm内核中)、ExtClassLoader、APPClassLoader加载器;
这里写图片描述

2、测试代码:

/** * 有3中类加载器,BootStrap(c++实现,嵌入在java内核中),ExtClassLoader,APPClassLoader * @author Rail * */public class ClassLoaderTest {    public static void main(String[] args){        System.out.println("classpath指定的目录的类的加载器:"+ClassLoaderTest.class.getClassLoader().getClass().getName());        //1--打印结果:自己编写的类的加载器:sun.misc.Launcher$AppClassLoader        //2--将ClassLoaderTest打成jar包,然后放入到目录F:\LAMP\Java\jdk1.8.0_45\jre\lib\ext中,打印结果:        //   jre/lib/ext/文件下的类 的加载器:sun.misc.Launcher$ExtClassLoader        System.out.println("ClassLoaderTest类的加载器 的父亲:"        +ClassLoaderTest.class.getClassLoader().getParent().getClass().getName());        //打印:ClassLoaderTest类的加载器 的父亲:sun.misc.Launcher$ExtClassLoader        System.out.println("ClassLoaderTest类的加载器 的父亲 的父亲:"        +ClassLoaderTest.class.getClassLoader().getParent().getParent());        //打印:ClassLoaderTest类的加载器 的父亲 的父亲:ClassLoaderTest类的加载器 的父亲 的父亲:null        System.out.println("rt.jar中的类的加载器:"+ArrayList.class.getClassLoader());        //打印结果为:系统类的加载器:null    }}

3、说明:

为什么类加载器有getParent()方法,类加载器之间的父子关系不是以继承(inheritance)的关系来实现,而是使用组合(composition)来复用父加载器的代码;
为什么下面代码打印不同的结果,类加载器这样的机制为双亲委派模型,一个类加载器如果收到类加载的请求,不是马上自己去加载,而是委派给父类加载器去加载,一直这样下去,到达顶层加载器后,顶层加载器搜索自己目录能否找到这个类,找到则加载,找不到则由子类加载器处理。例如java.lang.Object,当Object类由不同的类加载器来加载时,最后都是由顶层加载器来加载完成,这保证Object在各种类加载器环境下是一样的

System.out.println("classpath指定的目录的类的加载器:"+ClassLoaderTest.class.getClassLoader().getClass().getName());        //1--打印结果:自己编写的类的加载器:sun.misc.Launcher$AppClassLoader        //2--将ClassLoaderTest打成jar包,然后放入到目录F:\LAMP\Java\jdk1.8.0_45\jre\lib\ext中,打印结果:        //   jre/lib/ext/文件下的类 的加载器:sun.misc.Launcher$ExtClassLoader

注:继承(inheritance)和组合(composition)都是用来复用代码的,inheritance关系就是两个类有extends的关系,即is B,而composition则是,一个类(父)是包含了另一个类(子),Has B。

4、一个小练习,自己写一个类java.lang.String,然后实现如下:

package java.lang;public class String {    public String(String string) {    }    public  int indexOf(int i) {        return 100;    }}

在另外一个类中调用String类:

package jvm.classloader;public class ClassLoaderTest2 {    public static void main(String[] args){        String s = new String("abcdx");        char c = 'z';        System.out.println(s.indexOf(c));    }}

请问最终打印的是-1还是100,为什么?打印的是-1,原因和3中的第二点说明是一样的。

资料来源:
《深入理解JAVA虚拟机》
https://www.bilibili.com/video/av14894375/
http://www.cnblogs.com/cplinux/p/5703695.html
http://blogads.blog.163.com/blog/static/24008200820148200558801/

原创粉丝点击