当前位置 : 主页 > 编程语言 > java >

java类加载器有哪些

来源:互联网 收集:自由互联 发布时间:2023-03-22
java类加载器 有:1、引导类加载器;2、拓展类加载器;3、系统类加载器;4、用户自定义类加载器。其中,引导类加载器(Boostrap ClassLoader),又叫启动类加载器,由原生代码(如C语言

java类加载器有:1、引导类加载器;2、拓展类加载器;3、系统类加载器;4、用户自定义类加载器。其中,引导类加载器(Boostrap ClassLoader),又叫启动类加载器,由原生代码(如C语言)编写,不继承自java.lang.ClassLoader。负责加载核心Java库,存储在<JAVA_HOME>/jre/lib目录中。

1、引导类加载器

引导类加载器(Boostrap ClassLoader),又叫启动类加载器。由C/C++语言实现,嵌套在JVM内部。用来加载 Java 的核心库(JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.path路径下的内容),用于提供JVM自身需要的类。并不继承自 java.lang.ClassLoader,没有父加载器。是扩展类加载器和应用类加载器的父类加载器。出于安全考虑,Boostrap类加载器只加载包为java、javax、sun等开头的类。

引导类加载器是jvm在运行时,内嵌在jvm中的一段特殊的用来加载java核心类库的C++代码。String.class 对象就是由引导类加载器加载的,引导类加载器具体加载哪些核心代码可以通过获取值为 “sun.boot.class.path” 的系统属性获得。引导类加载器不是java原生代码编写的,所以其也不是java.lang.ClassLoader类的实例,其没有getParent方法。

2、拓展类加载器

扩展类加载器(Extension ClassLoader),Java语言编写,由sun.misc.Launcher类的内部类ExtClassLoader类实现,派生于ClassLoader类,父加载器为引导类加载器。从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建的jar包放在此目录下,也会自动由扩展类加载器加载。

拓展类加载器用来加载jvm实现的一个拓展目录,该目录下的所有java类都由此类加载器加载。此路径可以通过获取”java.ext.dirs”的系统属性获得。拓展类加载器就是java.lang.ClassLoader类的一个实例,其getParent方法返回的是引导类加载器(在 HotSpot虚拟机中用null表示引导类加载)。

3、系统类加载器

系统类加载器(System ClassLoader),也称为应用程序类加载器。根据 Java应用程序的类路径(java.class.path或CLASSPATH环境变量)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。该类由sun.misc.Launcher$AppClassLoader实现。

开发者可用通过 java.lang.ClassLoader.getSystemClassLoader()方法获得此类加载器的实例,系统类加载器也因此得名。其主要负责加载程序开发者自己编写的java类。一般来说,java应用都是用此类加载器完成加载的,可以通过获取”java.class.path”的系统属性(也就是我们常说的classpath)来获取应用类加载器加载的类路径。应用类加载器是java.lang.ClassLoader类的一个实例,其getParent方法返回的是拓展类加载器。

4、用户自定义类加载器

用户自定义类加载器(User-Defined ClassLoader),ClassLoader子类。

用户自定义类加载器实现:

  • 开发人员通过继承抽象类java.lang.ClassLoader类的方式,实现自己的类加载器,以满足一些特殊需求。
  • 不建议覆盖loadClass()方法,而是建议把自定义的类加载逻辑写在findCalss()方法中。
  • 在编写自定义类加载器时,如果没有太过于复杂的需求,可以直接继承URLClassLoader类,这样可以避免自己去编写findClass()方法以及获取字节码流的方式,使自定义类加载器编写更加简洁。

拓展阅读

类加载器的加载机制

当jvm要加载某个类时,jvm会先指定一个类加载器,负责加载此类。而此指定的类加载器在尝试自己去根据某个类的二进制名字查找其相应的字节码文件并定义之前,会首先委托给其父亲(getParent方法返回的类加载器)尝试加载,如果加载失败,就会由自己来尝试加载此类。一般情况下,这个由jvm指定的类加载器就是应用类加载器,jvm会自动调用其loadClass(String name)方法来开启类的加载过程。

‎Java.lang.ClassLoader 的方法‎

‎在对类发出 JVM 请求之后,需要执行几个步骤才能装入类。类按照委派模型加载,但有一些重要的方法或函数在加载类时起着至关重要的作用。‎

  • ‎loadClass(字符串名称,布尔解析):‎‎此方法用于加载 JVM 引用的类。它将类的名称作为参数。这是 loadClass(String, boolean) 的类型。‎
  • ‎defineClass()‎‎:defineClass() 方法是‎‎最终‎‎方法,不能重写。此方法用于将字节数组定义为类的实例。如果该类无效,则它抛出 ‎‎ClassFormatError‎‎。‎
  • ‎findClass(字符串名称):‎‎此方法用于查找指定的类。此方法仅查找但不加载类。‎
  • ‎findLoadedClass(字符串名称):‎‎此方法用于验证 JVM 引用的类以前是否被加载过。‎
  • ‎Class.forName(字符串名称,布尔值初始化,类加载器加载器):‎‎此方法用于加载类以及初始化类。此方法还提供了选择任何一个 ClassLoaders 的选项。如果类装入器参数为 NULL,则使用 Bootstrap 类装入器。‎

 

网友评论