JVM (二)类加载用的类库

  • java.lang.ClassLoader 抽象类,根据类名称,找到类的字节码,加载类,生成Class对象,获取类资源如配置文件

  • 引导加载类(bootstrap class loader)
用来加载java的核心类库的,使用原生代码来实现的(c++),并不继承自java.lang.ClassLoader

  • 扩展类加载库(extension class loader)
用来java的扩展库,由sunmisc.Launcher$ExtClassLoader实现,java实现,继承自java.lang.ClassLoader

  • 应用程序类加载器(application class loader)
根据java应用的类路径(classpath,java.class.path)加载类,由sunmisc.Launcher$AppClassLoader实现,java实现,继承自java.lang.ClassLoader

  • 自定义类加载器
通过继承java.lang.ClassLoader实现自己的类加载器 java实现


他们之间的关系是树形结构,但不是继承关系,而是组合使用关系


public class Demo02 {

public static void main(String[] args) {

System.out.println(ClassLoader.getSystemClassLoader());//当前使用的类加载器

System.out.println(ClassLoader.getSystemClassLoader().getParent());

//父亲类加载器,这个父亲指的是属性结构的父亲,不知继承关系

System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());
System.out.println(System.getProperty("java.class.path"));//当前类加载path的路径

}

输出


第三行是boostrap class loader,c++实现的所以java中无法访问

}

类加载器的代理模式

双亲委托机制(代理模式的一种)

       某个特定的类加载器在接到加载类的请求时,将任务委托给父类(树结构的父类)加载器,直到根节点的类加载器,如果该加载器无法加载类,再一层一层向下加载,直到加载成功,就返回。保证了Java核心库的类型安全,类加载器除了用于加载类,也是最安全的保障。比如java.lang.String类是java的核心类库,你要加载一个String类,采用双亲委托机制就会确保你加载到java核心类库的String类,而不是会有人自己定义的路径为java.lang.String类。

      但是并不是所有的类加载器都是用双亲代理模式机制,Tomcat服务器类加载器也是用代理模式,只是不是双亲委托机制,而是自己先去加载,加载不了,再给父类。

线程上下文类加载器

抛弃双亲委托机制,每一个线程都有一个关联的上下文类加载器,默认是系统类加载器,可以用下面第二个方法进行更改,比如更改为自定义的类加载器。

Thread.currentThread().getContextClassLoader();

Thread.currentThread().setContextClassLoader();


猜你喜欢

转载自blog.csdn.net/wangdongli_1993/article/details/80983693