JVM-ClassLoader

1. ClassLoader基本概念

与C或c++编写的程序不同,Java程序并不是一个可执行文件,而是由许多独立的类文件组成的,每一个文件对应一个Java类。此外,这些类文件并非全部都装入内存,而是根据程序需要遵渐载入。ClassLoader是JVM实现的一部分。
ClassLoader包括:
bootstrap classloader(启动类加栽器),ClassLoader在JVM运行的时候加载Java核心的API,以满足Java程序最基本的需求,其中就包括用户定义的ClassLoader,这里所谓的用户定义,是指通过Java程序实现的两个ClassLoader: -个ExtClassLoader,它的作用是用采加载Java的扩展API,也就是,lib/ext中的类;第二个是AppClassLoader,它是用来加载用户机器上CLASSPATH设置目录中的Class类,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoadcr进行加载。

2.ClassLoader加载流程

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

3.类加载的过程->父类委托模式

loadClass{
//首先检查该name的class是否被加载
Class c=findLoadClass(name);
if(c==null){
    if(parent!=null){
        //如果parent不为null,则调用parent的loadClass进行加载
        c=parent.loadClass(name,false);
    }else{
        //如果parent为null,则调用BootstrapClassLoader进行加载
        c=findBootstrapClass(name);
    }
}
//如果仍然没有加载成功,则调用自身的findClass进行加载
c=findClass(name);
if(resolve){
    reaolveClass(c);
}
return c;
}

从上面一段代码中可以看出,一个类加载的过程使用了一种父类委托模式。
为什么要使用这种父类委托模式呢?
1.这样可以避免重复加载,当父类已经加栽了该类的时候,就没有必要子ClassLoader再加载一次。
2.考虑到安全因素,如果不使用这种委托模式,那么可以随时使用自定义的String来动态替代Java核心API中定义的类型,这样会存在非常大的安全隐患,而父类委托的方式就可以避免这种情况,因为String已经在启动时被加载,所以,用户由定义类是无法加载一个自定义的ClassLoader。

重要方法

1. loadClass方法

ClassLoader.loadClass0是ClassLoader的入口点。该方法的定义如下:

Class loadClass(  String name, boolean resolve)
2. defineClass方法

defineClass方法接受由原始字节组成的数组,并把它转换成Class对象。原始数组包含如从文件系统或网络装入的数据。defineClass管理JVM的许多复杂的实现层面——它把字节码分析成运行时数据结构、校验有效性等。因为
defineClass方法被标记成final的,所以也不能覆盖它。

3. findSystemClass方法。

findSystemClass方法从本地文件系统装入文件。它在本地文件系统中寻找类文件,如果存在,就使用defineClsass将原始字节转换成Class对象,以将该文件转换成类。当运行Java应用程序时,这是JVM正常装入类的默认机制。对于
定制的ClassLoader,只有在尝试其他方法装入类之后,再使用findSystemClass。
这是因为ClassLoader是负责执行装入类的相关步骤,不负责所有类的所有信息。例如,即使ClassLoader从远程的Web站点装入了某些类,仍然需要在本地机器上装入大量的基本Java库。而这些类库不是我们所关心的,所以要JVM以默认
方式从本地文件系统装入它们,这就是findSystemClass的用途。

4. resolveClass方法

正如前面所提到的,可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的loadClass时,可“调用resolveClass,这取决于loadClass的resolve参数的值。

5. findLoadedClass方法

findLoadedClass充当一个缓存:当请求loadClass装入类时,它调用该方法来查看ClassLoader是否已装入这个类,这样可以避免重新装八已存在类所造成的麻烦。

6.findClass方法:

loadClass默认实现调用这个新方法。findClass的用途包含ClassLoader的所有特殊代码,而无须要复制其他代码(例如,当专门的方法失败时,调用系统ClassLoader)。

为了创建自己的类装载器,应该扩展ClassLoader类,这是一个抽象类,可以创建一个
FileClassLoaderextends ClassLoader,然后覆盖ClassLoader中的findClass( String name)方法,这个方法通过类的名字而得到一个Class对象。

这里写图片描述

8) forName方法

Class类中有一个静态方法forName,这个方法和ClassLoader中的loadClass方法的目的一样,都是用来加载class的,但是两者在作用上却有所区别。

这里写图片描述

这里写图片描述

在Java API文档中,loadClass方法的定义是protected,也就是说,该方法是被保护的,而用户使用的方法是一个参数,一个参数的loadclass方法实际上就是调用了两个参数,第二个参数默认为false。因此,在这里可得看出通过loadClass加载类实际上就是加载的时候并不对谊类进行解释,因此不会初始化该类。而Class粪的forName方法则相反,使用forName加载的时候就会将Class进行解释和初始化。

下 面给出的Java中ClassLoader中的描述,哪些描述是正确的? ( )
A. ClassLoader没有层次关系
B.所有类中的ClassLoader都是AppClassLoader
c.通过Class.forName(String className),能够动态加载一个类
D.不同的ClassLoader加载同一个Class文件,所得的类是相同的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM中的双亲委派机制是一种类加载机制,它规定了在Java中一个类被加载时如何进行类加载器的选择。根据这个机制,当一个类需要被加载时,首先会由类加载器ClassLoader检查是否已经加载过该类,如果是,则直接返回已经加载过的类;如果不是,则将该请求委派给父类加载器去加载。这样的过程会一直向上委派,直到达到顶层的引导类加载器(Bootstrap ClassLoader)。引用 引用中提到,并不是所有的类加载器都采用双亲委派机制。Java虚拟机规范并没有强制要求使用双亲委派机制,只是建议使用。实际上,一些类加载器可能会采用不同的加载顺序,例如Tomcat服务器类加载器就是采用代理模式,首先尝试自己去加载某个类,如果找不到再代理给父类加载器。 引用中提到,引导类加载器(Bootstrap ClassLoader)是最早开始工作的类加载器,负责加载JVM的核心类库,例如java.lang.*包中的类。这些类在JVM启动时就已经被加载到内存中。 综上所述,JVM的双亲委派机制是一种类加载机制,它通过类加载器的委派方式来加载类,首先检查是否已经加载过该类,如果没有则委派给父类加载器去加载,直到达到顶层的引导类加载器。不过,并不是所有的类加载器都采用该机制,一些类加载器可能会采用不同的加载顺序。引用<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JVM-双亲委派机制](https://blog.csdn.net/m0_51608444/article/details/125835862)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [jvm-双亲委派机制](https://blog.csdn.net/y08144013/article/details/130724858)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值