java类装载(ClassLoader)

类装载器ClassLoader

类装载器把一个类装载到JVM的过程:
  • 加载:查找和导入类的字节码文件.class文件
  • 链接:校验、准备、解析
  1. 校验:校验加载的Class文件的完整性
  2. 准备:给类的静态变量分配存储空间
  3. 解析:将符号引用转成直接引用
  • 初始化:初始化静态变量、执行静态代码块。
JVM的类装载过程

JVM中有三类ClassLoader:

  • 根装载器(C++编写的,负责装载JRE的核心类库)
  • ExtClassLoader(扩展类装载器,负责装载JRE根目录下ext文件夹下的JAR类包)
  • AppClassLoader(负载装载ClassPath路径下的JAR包)

java的类装载采用双亲委托机制:

  • 当启动一个线程时,比如执行main方法的线程,对于这个线程中需要加载的第一个类,比如main方法所在的主类A,当前线程的类加载器会执行类A的加载任务,
  • 类加载器首先检查自己的类缓存池中是否已经有要加载的类,如果有,则返回。如果没有则将任务委托给parent ClassLoader,如此依次向上委托
  • 直到parent为null时,这时JVM会从bootStrp ClassLoader的类缓存池中查找要加载的类,因为JRE核心类是bootStrp ClassLoader加载的,但是根加载器是C++实现的,不是一个Java类,所以当parent为null时,就需要查找根加载器的缓存池。
  • 如果委托过程中有从某个parent的缓存池中找到要加载的类,则直接返回此类的引用,如果没有则返回null,最初发起委托的加载器接到null值后,自行加载:查找Class文件,导入到JVM中,校验、准备、解析、初始化,最终在自己的类缓存池中,存放一个此类的类对象。

类加载的双亲委托机制的目的–能够防止黑客攻击。

  • 如果黑客仅仅是写了个java.lang.String类,篡改了一部分代码,这个行为不会对正常的程序产生任何影响:因为双亲委托机制会导致黑客自定义的这个类永远也不会被加载和使用。假如用户的正常程序中用到了String类,但是JVM启动时首先就已经加载了String类,并存储在bootStrp ClassLoader的缓存池中,那么当运行到用户程序,需要加载String类时,经过委托,必定是先在缓存池中找到,而不需加载黑客定义的String类。
  • 如果黑客不仅自定义了一个java.lang.String类,同时也自定义了一个ClassLoader加载了这个String类。这仍然对用户的程序不会造成任何影响。因为用户的程序中用到的类不是通过黑客自定义的ClassLoader加载的,那么用户程序中用到String类时,通过双亲委托机制仍然找到的是bootstrp ClassLoader的类缓存池中的String类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值