一、

1.类加载器

自定义类加载器 > 系统类加载器 > 扩展类加载器 > 引导类加载器
JVM笔记 详解Class加载过程(二)

  • 加载过程:

当一个类需要加载,首先由自定义类加载器加载,但不是由自己先去加载,而是把这个请求委托给父亲的加载器去执行,依次向上,如果到了顶级加载器不能加载此类,则向下委托,由子类加载器尝试加载。
JVM笔记 详解Class加载过程(二)

2.为什么要使用这种双亲委托模式呢?

因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。

考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的ClassLoader。

思考:假如我们自己写了一个java.lang.String的类,我们是否可以替换调JDK本身的类?
答案是否定的。我们不能实现。为什么呢?我看很多网上解释是说双亲委托机制解决这个问题,其实不是非常的准确。因为双亲委托机制是可以打破的,你完全可以自己写一个classLoader来加载自己写的java.lang.String类,但是你会发现也不会加载成功,具体就是因为针对java.*开头的类,jvm的实现中已经保证了必须由bootstrp来加载。

因加载某个类时,优先使用父类加载器加载需要使用的类。如果我们自定义了java.lang.String这个类, 加载该自定义的String类,该自定义String类使用的加载器是AppClassLoader,根据优先使用父类加载器原理, AppClassLoader加载器的父类为ExtClassLoader,所以这时加载String使用的类加载器是ExtClassLoader, 但是类加载器ExtClassLoader在jre/lib/ext目录下没有找到String.class类。然后使用ExtClassLoader父类的加载器BootStrap, 父类加载器BootStrap在JRE/lib目录的rt.jar找到了String.class,将其加载到内存中。这就是类加载器的委托机制。

相关文章:

  • 2021-05-07
  • 2021-11-05
  • 2021-09-24
  • 2022-12-23
  • 2021-06-28
  • 2021-06-12
  • 2021-11-18
  • 2021-09-22
猜你喜欢
  • 2022-01-01
  • 2021-05-23
  • 2021-11-05
  • 2021-12-15
  • 2021-07-20
  • 2021-06-08
相关资源
相似解决方案