当前位置: 首页 > 编程笔记 >

classloader类加载器_基于java类的加载方式详解

徐绪
2023-03-14
本文向大家介绍classloader类加载器_基于java类的加载方式详解,包括了classloader类加载器_基于java类的加载方式详解的使用技巧和注意事项,需要的朋友参考一下

基础概念

Classloader 类加载器,用来加载 Java 类到 Java 虚拟机中。与普通程序不同的是。Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。

JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用本地代码实现的,它负责加载核心JavaClass(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由BootstrapClassLoader加载;其中Extension ClassLoader负责加载扩展的Javaclass(例如所有javax.*开头的类和存放在JRE的ext目录下的类),ApplicationClassLoader负责加载应用程序自身的类。

当运行一个程序的时候,JVM启动,运行bootstrapclassloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。

注: 学ClassLoader看OSGI程序应用

什么时候JVM会使用ClassLoader加载一个类呢?当你使用java去执行一个类,JVM使用ApplicationClassLoader加载这个类;然后如果类A引用了类B,不管是直接引用还是用Class.forName()引用,JVM就会找到加载类A的ClassLoader,并用这个ClassLoader来加载类B。JVM按照运行时的有效执行语句,来决定是否需要装载新类,从而装载尽可能少的类,这一点和编译类是不相同的。

Why use your own ClassLoader?

似乎JVM自身的ClassLoader已经足够了,为什么我们还需要创建自己的ClassLoader呢?

因为JVM自带的ClassLoader只是懂得从本地文件系统加载标准的java class文件,如果编写你自己的ClassLoader,你可以做到:

1)在执行非置信代码之前,自动验证数字签名

2)动态地创建符合用户特定需要的定制化构建类

3)从特定的场所取得java class,例如数据库中

4) 等等

事实上当使用Applet的时候,就用到了特定的ClassLoader,因为这时需要从网络上加载java class,并且要检查相关的安全信息。

应用服务器大都使用了ClassLoader技术,即使你不需要创建自己的ClassLoader,了解其原理也有助于更好地部署自己的应用。

重点注明:其实一个已经加载的类是无法被更新的,如果你试图用同一个ClassLoader再次加载同一个类,就会得到异常(java.lang.LinkageError: duplicate classdefinition),我们只能够重新创建一个新的ClassLoader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被内存回收了,那么JVM就会在适当的时候把不会再使用的类卸载。

绝大部分Java程序都会使用3种系统提供的类加载器

1.启动类加载器(Bootstrap ClassLoader),负责将存在<JAVA_HOME>\lib目录中的,或被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机里.注意是按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载。

2.扩展类加载器(ExtClassLoader),它负责<JAVA_HOME>\lib\ext目录中的,或被java.ext.dirs系统变量所指定的路径中的所有类库.

3.应用程序类加载器(App-ClassLoader),通过cassLoader.getSystemClassLoader()获取,它负责加载用户类路径(ClassPath)上所指定的类库,一般情况下这个是程序中默认的类加载器.

双亲委托模式 是Java设计者推荐给开发者的一种类加载实现方式.双亲委托模型的工作过程是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成.每一层次的类加载器都是如此,因此所有的加载请求最终都会传送到顶层的启动类加载器中,只有当父类加载器没有找到所需的类时,子加载器才会尝试自己去加载。双亲模式的好处是Java类随着它的类加载器一起具备了一种带优先级的层次关系。例如类Object,存放在rt.jar中,无论哪个类加载器加载这个类,最终都是委派给处于模型最顶端的启动类加载,因此Object类在程序使用多种类加载器环境中依然能保证是同一个类。相反,如果没有使用双亲模型,就可能出现用户自己编写一个Object类,导致系统中出现多个不同的Object类,这样Java类型体系中最基础的行为也就无法保证。

以上这篇classloader类加载器_基于java类的加载方式详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小牛知识库。

 类似资料:
  • 一、类加载机制 1.定义: 把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。 在Java语言里,类型的加载、连接和初始化过程都是在程序运行期间完成的,这种策略虽然会令类加载时稍微增加一些性能开销,但是会为Java应用程序提供高度的灵活性,Java里天生可以动态扩展的语言特性就是依赖运行期动态加载和动态连接这个特点来实现的。

  • 本文向大家介绍java 类加载与自定义类加载器详解,包括了java 类加载与自定义类加载器详解的使用技巧和注意事项,需要的朋友参考一下 类加载 所有类加载器,都是ClassLoader的子类。 类加载器永远以.class运行的目录为准。 读取classpath根目录下的文件有以下几种方式: 1 在Java项目中可以通过以下方式获取classspath下的文件: 在Tomcat中tomcat又声明了

  • 简介 Java类加载器是Java运行时环境(Java Runtime Environment)的一部分,负责动态加载Java类到Java虚拟机的内存空间中。类通常是按需加载,即第一次使用该类时才加载。 由于有了类加载器,Java运行时系统不需要知道文件与文件系统。每个Java类必须由某个类加载器装入到内存。 类装载器子系统涉及Java虚拟机的其他几个组成部分,以及几个来自java.lang库的类。

  • 问题内容: 如果我有一个内部类声明,例如: 其次是: A $ B内部类也将被加载吗?如果B内部类未声明为“静态”怎么办? 问题答案: 一旦代码被编译, 就没有内部类之类的东西 。如果查看的结果,则会看到两个文件: 因此,类在加载时不会加载,只是 碰巧 在中定义了。 编辑 例如,鉴于这两个文件, 和一个文件(为方便起见): 首先,通过运行进行构建。然后,解压缩生成的JAR文件(位于中): 打开每个文

  • CLMAIN->clA(类A,$B)。$B是类a的内部类B。 从clMain创建具有指定url的新clA到包含类A(和类$B)的jar文件。然后通过CLA创建新对象A。 从X加载的另一个类通过接口执行对象a的方法没有问题。 然后,在该方法中,应该创建新对象$b,但它抛出. 在类A的构造函数中加载类$B可以解决以下问题:

  • 问题内容: 我有一个加载从源文件编译的类。但是,当我更改源文件,保存并重新编译它时,仍然会加载该类的第一个版本。 我想念什么?像newInstance之类的东西? 问题答案: 类加载器不能替换已经加载的类。将返回现有实例的引用。 您必须实例化一个新的类加载器,并使用它来加载新类。然后,如果要“替换”该类,则必须扔掉该类加载器并创建另一个新的类加载器。 针对您的评论:做类似的事情 该类加载器将使用“