ClassLoader

ClassLoader:

Java程序并不是一个可执行文件,而是由许多独立的类文件组成,每个文件对应一个类,这些类文件并非全部装入内存,而是根据程序需要逐渐载入

ClassLoader是JVM实现的一部分,ClassLoader在JVM运行时加载Java核心的API,其中包括用户定义的ClassLoader,这里的用户定义是指通过java程序实现的两个ClassLoader:

·ExtClassLoader:用来加载Java的扩展API,即/lib/ext中的类;

·APPClassLoader:用来加载要换机器上的CLASSPATH设置目录中的Class的。(默认是此)

ClassLoader加载流程:

1)当运行一个程序是,JVM启动,运行bootstrap classloader(启动类加载器),该ClassLoader加载核心API(同时ExtClassLoader和APPClassLoader也加载),

2)然后调用ExtClassLoader加载扩展API

3)最后调用APPClassLoaderCLASSPATH目录下定义的Class

Classloader中的一段代码:

protected synchronized Class loadClass(String name,boolean resolve)   throws ClassNotFoundException{

Class c =findLoadedClass(name);    ///首先检查那么指定的class是否被加载

if(c == null) {  ///没有被加载

try {

if(parent != null) {   ///如果parent不是null  则调用parent的方法(情况1

c = parent.loadClass(name,false);

}else {

c = findBootstrapClass0(name);    ///否则使用Bootstrap Classloader进行加载(情况2

}

}catch(ClassNotFoundException e) {

c = findClass(name);   ///如果仍然无法加载成功,那么调用自身的findClass进行加载(情况3

}

}

if(resolve) {

resolveClass(c);

}

return c;

}

上述代码使用了一种父委托模式,原因如下:

  1. 可以避免重复加载,当父已经加载过了就没必要在加载了;
  2. 安全;如果不采用此方式则可以随时使用自定义的String来动态替代Java核心API中定义的类型,存在隐患;

 

一些重要方法的介绍:

1.loadClass方法:   Class  loadClass (String name,boolean resolve)

是ClassLoader的入口点;name是JVM需要的类的名称,resolve参数是告诉方法是否需要解析

(如个JVM只需要知道这个类是否存在或者找出该类的超类,那么就不需要解析)

    2.defineClass方法:

接收由原始字节组成的数组,并把它转为Class对象。  原始数组包含从文件系统或网络装入的数据,

defineClass 可以把字节码分析成运行时数据结构、校验有效性

且此方法为final型,所以不能被覆盖。

3.findSystemClass方法:

此方法时从本地文件系统装入文件,先是在文件系统中寻找类文件,如果存在就是要defineClass方法原始字节转为class对象;(以将文件转为类)  这是JVM装入类的默认机制

对于定制的ClassLoader只有在尝试其他方法装入类后,再使用findSystemClass。

4.resolveClass方法:

程序可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类;

5.findLoadedClass方法:

此方法充当一个缓存,可以了查看ClassLoader是否已经装入这个类(可以避免重复装载)

6.findClass方法:

LoadClass默认实现调用这个新方法,此方法的用途包含ClassLoader所有特殊代码,而无需复制其他代码。

目的是从本地文件系统使用实现的类装载器装载一个类,为了创建自己的类装载器,应该是扩展ClassLoader类,这是一个抽象类;;;该方法是通过类的名字得到一个class对象

7.getSystemClasssLoader方法

如果覆盖findClass或loadClass,此方法可以以实际的ClassLoader对象访问系统的ClassLoader。

8.forName方法:(能够动态加载一个类)

Class中有一个静态的方法forName,这个方法和ClassLoader中的loadClass方法目的意义,都是用来加载class的,再是两种在作用上却有区别。

1、Class clazz = Class.forName(“name”);

2、ClassLoader  c1 = Thread.currentThread().getContextClassLoader();    

Class clazz = c1.loadClass(“name”);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值