ClassLoader的理解

ClassLoader顾名思义就是用来加载Class文件到JVM,以供程序使用的,java程序可以动态加载类定义,而这个动态加载的机制就是通过ClassLoader来实现的

 

ClassLoader的类型有很多,但是最重要的是Bootstrap Classloader,这个是启动类加载器,这个ClassLoaderJVM运行时候加载java的核心的API以满足java程序的基本需求,这就包括了其他的ClassLoader,其中包括用户自定义的ClassLoaderExtClassLoader,还有一个是AppClassLoader

 

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

 

在定义一个ClassLoader的时候都必须继承ClassLoader这个抽象类,而每个ClassLoader都会有一个parent ClassLoader,我们可以看一下ClassLoader这个抽象类中有一个getParent()方法,这个方法用来返回当前ClassLoaderparent,注意,这个parent不是指的被继承的类,而是在实例化该ClassLoader时指定的一个ClassLoader,如果这个parentnull,那么就默认该ClassLoaderparentBootstrap Classloader。 

 

 

如果自定义了一个UserClassLoader,使用这个自定义的ClassLoader加载java.lang.String,那么这里String是否会被这个ClassLoader加载呢?事实上java.lang.String这个类并不是被这个UserClassLoader加载,而是由Bootstrap Classloader进行加载,这就是双亲委托模式机制,也就是在任何一个自定义ClassLoader加载一个类之前,它都会先委托它的父亲ClassLoader进行加载,只有当父亲ClassLoader无法加载成功后,才会由自己加载

在ClassLoader中的一段源代码中有描述: 

Java代码  

 

protected synchronized Class loadClass(String name, boolean resolve)  
throws ClassNotFoundException  
   {  
// 首先检查该name指定的class是否有被加载  
 Class c = findLoadedClass(name);  
 if (c == null) {  
     try {  
    if (parent != null) {  
        //如果parent不为null,则调用parent的loadClass进行加载  
  = parent.loadClass(name, false);  
    } else {  
        //parent为null,则调用BootstrapClassLoader进行加载  
        c = findBootstrapClass0(name);  
    }  
    } catch (ClassNotFoundException e) {  
        //如果仍然无法加载成功,则调用自身的findClass进行加载              
        c = findClass(name);  
    }  
}  
if (resolve) {  
    resolveClass(c);  
}  
return c;  
   }  


 

这种双亲委托模式可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。还有一个原因就是如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患

 

ClassLoader加载class的时候会经过三步装载、连接、初始化。

其中装载就是找到相应的class文件,读入JVM;连接分三步,第一步是验证class是否符合规格,第二步是准备,就是为类变量分配内存同时设置默认初始值,第三步就是解释。初始化就是将类实例化成对象,以待其他应用程序使用。

 

其实ClassLoader就这样简单,知道了这些原理和理论,如果项目或者产品中遇到使用ClassLoader的情况就应该会非常轻松。 

ClassLoader是Java虚拟机(JVM)的一个重要组件,它负责在运行时动态加载Java类文件到内存中。ClassLoader的主要作用是根据类的全限定名(包括包名和类名)查找并加载对应的字节码文件,然后将字节码转换为JVM可以理解的运行时数据结构,最终生成可执行的Java类。 ClassLoader的工作原理是通过双亲委派模型来实现的。当一个类需要被加载时,ClassLoader首先会将请求委派给其父类加载器,如果父类加载器无法找到该类,则会尝试自己加载。这种层级关系的设计可以保证类的加载顺序和一致性,并且可以防止重复加载同一个类,提高了系统的安全性和效率。 ClassLoader可以根据不同的需求使用不同的实现,比如系统类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用类加载器(Application ClassLoader)。系统类加载器负责加载JDK中的核心类库,扩展类加载器用于加载JDK扩展目录中的类库,而应用类加载器则负责加载应用程序的类。 除了默认的三种ClassLoader,Java还提供了自定义ClassLoader的能力,开发人员可以根据需要实现自己的ClassLoader来加载特定位置或者特定格式的类文件。自定义ClassLoader可以用于实现类似热部署、插件化等功能,扩展了Java的灵活性和可扩展性。 总之,ClassLoader在Java中起到了类加载的重要作用,它实现了类的动态加载和运行时的动态链接,为Java应用程序提供了更大的灵活性和可扩展性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值