类加载的过程?类的加载机制?类加载器的种类?双亲委派机制优点和打破?

类加载的过程?

在这里插入图片描述

类的加载机制?

JVM使用Java类的流程如下:

1,Java源文件----编译---->class文件
2,类加载器ClassLoader会读取这个.class文件,并将其转化为java.lang.Class的实例。有了该实例,JVM就可以使用他来创建对象,调用方法等操作了。

那么ClassLoader是以一种什么机制来加载Class的?这就是我们要谈的类的加载机制!

搞清楚这个问题,首先要知道,我们用到的Class文件都有哪些来源?

1,Java内部自带的核心类,位于$JAVA_HOME/jre/lib,即rt.jar。

2,Java的扩展类,位于$JAVA_HOME/jre/lib/ext目录下。
3,我们自己开发的类或项目开发用到的第三方jar包,位于我们项目的目录下,比如WEB-INF/lib目录。

类加载器的种类?

1,Java核心类,这些Java运行的基础类,由一个名为BootstrapClassLoader加载器负责加载。这个类加载器被称为根加载器或启动类加载器,默认负责加载%JAVA_HOME%lib下的jar包和class文件。
注意:BootstrapClassLoader不继承ClassLoader,是由JVM内部实现。法力无边,所以你通过java程序访问不到,得到的是null。
2,Java扩展类,是由ExtClassLoader负责加载,被称为“扩展类加载器”。负责加载%JAVA_HOME%/lib/ext文件夹下的jar包和class类。
3,项目中编写的类,是由AppClassLoader来负责加载,被称为“系统类加载器”,负责加载classpath下的类文件,引用的类,又称线程上下文加载器。
4、用户自定义加载器,加载自定义路径下的类包。
在这里插入图片描述

类加载机制两种:全盘负责委托机制和双亲委派机制
全盘委托类加载机制:除非显示该类使用一个加载器,否则将该类和所属依赖的类库都加载一遍。

双亲委派机制?优点?怎样打破?

在这里插入图片描述

所谓双亲委托机制,就是加载一个类,会先获取到一个系统类加载器AppClassLoader的实例,然后往上层层请求,先由BootstarpClassLoader去加载,如果BootStrapClassLoader发现没有,再下发给ExtClassLoader去加载,还是没有,才由AppClassLoader去加载。如果还是没有,则报错。

请问,我现在编写一个类,类全名如下:java.lang.String,我们知道JDK也给我们听过了一个java.lang.String,那么,我们编写的这个String类能否替换到JDK默认提供,也就是说程序实际运行的时候,会加载我们的String还是JDK的String?为什么?

JDK提供java.lang.String类,默认在rt.jar这个包里面,所以,默认会由BootstarpClassLoader加载,所以,我们自己编写的java.lang.String,都没有机会被加载到。

优点:

  1. 沙箱安全 防止核心类库被修改,避免用户自己编写的类动态替换Java的一些核心类,如自己写的java.lang.String不被使用一样。
  2. 避免类的重复加载 父类加载器加载过了,子加载器不需要再重新加载。因为 JVM中区分不同类,不仅仅是根据类名,相同的 class文件被不同的 ClassLoader加载就是不同的两个类。

怎样打破?

  1. 使用自定的类加载器
  2. 使用全盘委托类加载机制。

双亲委派机制是Java中的一种类加载机制,它的优点是可以保证Java核心库的安全性和稳定性。但是在某些场景下,我们需要打破双亲委派机制,例如在Tomcat部署多个war包热部署时,如果不打破双亲委派机制,可能会导致不同的war包使用相同的类加载器,从而出现类冲突的问题。

打破双亲委派机制的方法是通过自定义类加载器来实现。自定义类加载器可以继承ClassLoader类,并重写findClass()方法,在该方法中实现自己的类加载逻辑在加载类时,首先会委托父类加载器加载,如果父类加载器无法加载,则由自定义类加载器加载。

需要注意的是,打破双亲委派机制可能会导致类加载的混乱和安全问题,因此在使用自定义类加载器时需要谨慎,并且需要遵循一定的规范和约定。

打破双拼委派机制的场景?

  1. tomcat 部署多个war包
  2. 热部署 加载进来的不是一样的
  3. jdbc 不同的driver驱动包
    … …

查看当前的类加载器:

System.out.println(this.getClass().getClassLoader());
System.out.println(this.getClass().getClassLoader().getParent());//查看父加载器
根加载器:null 扩展类加载器:
ExtClassLoader
系统类加载器:AppClassLoader

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值