首页 > 编程语言 >java ClassLoader笔记(一)

java ClassLoader笔记(一)

时间:2023-09-04 15:01:56浏览次数:37  
标签:java name parent ClassLoader jar 笔记 Class 加载


作者:fbysss
关键字:ClassLoader

一、Sun JDK Classloader体系

1.层次关系

Bootstrap: 加载rt.jar

<-Extension:加载 jre/ext/*.jar 

<-System:加载CLASSPATH中的jar

<-UserDefined加载用户自定义包类

2.特殊点

   Bootstrap ClassLoader为C++所写,Extension ClassLoader的parent为null,其中,getParent返回实例化本ClassLoader的ClassLoader,并不是superClass。

3.上级委托

很反感“双亲委托”这个翻译。给人第一印象要两个类去委托,而且,很容易感觉是继承关系。上级委托多好,立马减轻了理解难度。

上级委托的优点:

a.避免父子重复加载

b.避免jdk核心类被替代。比如String.class,在rt.jar包中。如果用户自己写了一个恶意代码,

由此想象一下我们经常遇到的,不同版本的jar包,出现冲突的原因(未经测试):

testv1.jar

testv2.jar

a.如果两个包是独立的,不被其他包中的class引用:

   如果两个包中的文件个数和名称完全一致,不会有冲突。因为同样的版本只加载一次。

   如果v2中有新的类,而加载的是testv1.jar,v2的新类就可能使用到v1的其他旧类,导致方法找不到或者逻辑错乱。

   如果加载的是testv2.jar,而v2是向下兼容,只增加类和方法,没有冲突。因为v1的类都不加载

   如果加载的是testv2.jar,只是删除了旧版本一些相对独立的类,这样旧版本中的这些类会被加载,并可以正常使用。

b.如果test包还有其他类引用,那就不好说了。类似上述情况,可能会出现冲突。

  

二、源码理解

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;   
   }

从这里也可以了解,ClassNotFoundException是因为什么情况产生了。就是当前类的类加载器没有找到对应jar或class文件。

Class.forname(String clazzName)实际上是使用了一个默认的类加载器,

public static Class<?> forName(String className) 
                throws ClassNotFoundException {
        return forName0(className, true, ClassLoader.getCallerClassLoader());
    }

从这里可以看出,使用的是调用Class.forname这个类所被加载的类加载器,对于一般的应用,就是SystemClassLoader,sun.misc.Launcher$AppClassLoader是一个实现

 

工具代码:用于查看Extension ClassLoader所加载的包

try {
   URL[] extURLs = ((URLClassLoader) ClassLoader
     .getSystemClassLoader().getParent()).getURLs();

   for (int i = 0; i < extURLs.length; i++) {

    System.out.println(extURLs[i]);

   }

  } catch (Exception e) {
  }

其他:

JVM中,一个类是否装载,由其fully qualified class name,也就是加包名的完整类名如com.sss.test.Test,及其装载器唯一决定。

也就是说,即使是同一个类,如果装载器不同,就可能被装载多次。

后记:

本想就写一篇笔记,但ClassLoader涉及的内容很多,还是一点一点来吧。

标签:java,name,parent,ClassLoader,jar,笔记,Class,加载
From: https://blog.51cto.com/u_16245757/7350858

相关文章

  • java 实现网址的截图
     maven引入<!--自动化测试工具,需要去其他网址下第三方包--><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version><exclusions><exclusio......
  • 【校招VIP】前端JavaScript语言之跨域
    考点介绍:什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。跨域是前端校招的一个重要考点,在面试过程中经常遇到,需要着重掌握。本期分享的前端算法考点之大数据相关,分为试题、文章以及视频三部分。答案详情解析和文章内容可点击下方......
  • SpringCloud笔记
    微服务技术栈:                                              ......
  • 无涯教程-JavaScript - CUBEMEMBER函数
    描述CUBEMEMBER函数从多维数据集返回一个成员或元组。使用此函数可以验证多维数据集中是否存在成员或元组。语法CUBEMEMBER(connection,member_expression,[caption])争论Argument描述Required/OptionalconnectionNameoftheconnectiontothecube-Atextstr......
  • java实现发邮件功能的三种方式
    在Java中,有多种不同的方法可以实现发送邮件的功能。以下是几种常用的方法:使用JavaMailAPI:importjava.util.Properties;importjavax.mail.*;importjavax.mail.internet.*;publicclassEmailSender{publicstaticvoidsendEmail(Stringsender,Stringreceiver,Str......
  • 无涯教程-JavaScript - CUBEKPIMEMBER函数
    描述该函数返回关键绩效指标(KPI)属性,并在单元格中显示KPI名称。语法CUBEKPIMEMBER(connection,kpi_name,kpi_property,[caption])争论Argument描述Required/OptionalconnectionNameoftheconnectiontothecube-AtextstringRequiredkpi_nameNameoft......
  • 【刷题笔记】35. Search Insert Position
    题目Givenasortedarrayandatargetvalue,returntheindexifthetargetisfound.Ifnot,returntheindexwhereitwouldbeifitwereinsertedinorder.Youmayassumenoduplicatesinthearray.Example1:Input:[1,3,5,6],5Output:2Example2:I......
  • Java语言基础知识全总结
    一.Java的优点1.      跨平台性。一次编译,到处运行。Java编译器会将Java代码编译成能在JVM上直接运行的字节码文件,C++会将源代码编译成可执行的二进制代码文件,所以C++执行速度快2.      纯面向对象。Java所有的代码都必须在类中书写。C++兼具面向对象和面向过程的特......
  • FFT & NTT 学习笔记
    FFTFFT是一种高效实现DFT和IDFT的方式,可以在\(O(n\logn)\)的时间内求多项式的乘法。多项式的点值表示不同于用每项的系数来表示一个多项式,我们知道对于给定的\(n+1\)个点值,可以确定唯一的\(n\)次多项式。这种用点值表示多项式的方法叫点值表示法。如果知道\(F(x......
  • Java元注解
    工作过程中遇到以下需求:校验某些类的某些字符串属性的长度。由于不想对所有的类和属性进行枚举检查,因此,我想通过在类上添加自定义注解的方式过滤出这些类以及属性。故学习一下Java的元注解。Java元注解这里需要说一下Java的内置注解,因为Java里有几个针对注解的注解,即元注解。@......