文章目录

  • 前言
  • 一、类加载过程
    • 1.加载
    • 2.验证
    • 3.准备
    • 4.解析
    • 5.初始化
  • 二、什么是 ClassLoader
    • ClassLoader 作用:
    • 1、ClassLoader 类结构分析
    • 2.ClassLoader 的等级加载机制
    • 3.ClassLoader加载类的原理
  • 三、同名类加载顺序
  • 总结

前言

在本地domain的一次更新jar包之后,本地的某个function直接挂了,经过检查,发现是是由于两个不同包的同名类,同名类的内部代码不同,导致代码校验类型出错。


为了方便理解,我们先从类加载过程开始讲起

一、类加载过程

(原文 https://segmentfault.com/a/1190000023876273 )
先在方法区找class信息,有的话直接调用,没有的话则使用类加载器加载到方法区(静态成员放在静态区,非静态成功放在非静态区),静态代码块在类加载时自动执行代码,非静态的不执行;先父类后子类,先静态后非静态;静态方法和非静态方法都是被动调用,即不调用就不执行。
类加载的流程如下:

1.加载

  • 通过类的全名限定获取定义此类的二进制字节流。
  • 将字节流代表的静态存储结构转化为方法区的运行时数据结构。
  • 在内存(方法区)生成一个代表这个类的class对象,作为方法区这个类的各种数据访问入口。

加载和连接是交叉进行的,加载未完成可能连接已经开始了。

2.验证

​ 检查class是否符合要求,非必须阶段,对程序的运行期没有影响,-Xverif:none 关闭(可以提高启动速度)

  • 文件格式验证(魔数、常量类型);
  • 元数据验证(语义分析);
  • 字节码验证(语义合法);
  • 符号引用验证;

3.准备

​ 正式为类变量(static成员变量)分配内存并设置类变量初始值(零值)的阶段,这个变量所使用的内存都将在方法区进行分配,这时候的内存分配仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起在堆中进行分配。

4.解析

​ 虚拟机将常量池内的符号引用替换为直接引用的过程。

5.初始化

​ 初始化阶段是执行类构造器<clinit>()方法的过程,虚拟机会保证一个类的类构造器()在多线程环境中被正确的加锁,同步;如果多个线程同时初始化一个类,那么只会有一个线程区执行这个类的类构造器,其他线程阻塞等待,直到<clinit>()方法完毕,同一个类加载器,一个类只会被初始化一次。


二、什么是 ClassLoader

(https://segmentfault.com/a/1190000008491597)
当程序在运行时,即会调用该程序的一个入口函数来调用系统的相关功能,而这些功能都被封装在不同的 class 文件当中,所以经常要从这个 class 文件中要调用另外一个 class 文件中的方法,如果另外一个文件不存在的,则会引发系统异常。而程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是根据程序的需要,通过Java的类加载机制(ClassLoader)来动态加载某个 class 文件到内存当中的,从而只有 class 文件被载入到了内存之后,才能被其它 class 所引用。所以 ClassLoader 就是用来动态加载 class 文件到内存当中用的。

ClassLoader 作用:

  • 负责将 Class 加载到 JVM 中
  • 审查每个类由谁加载(父优先的等级加载机制)
  • 将 Class 字节码重新解析成 JVM 统一要求的对象格式

1、ClassLoader 类结构分析

class loader 是一个负责加载 classes 的对象,ClassLoader 类是一个抽象类,需要给出类的二进制名称,class loader 尝试定位或者产生一个 class 的数据,一个典型的策略是把二进制名字转换成文件名然后到文件系统中找到该文件。

以下是 ClassLoader 常用到的几个方法及其重载方法:

  • ClassLoader
  • defineClass(byte[], int, int) 把字节数组 b中的内容转换成 Java 类,返回的结果是java.lang.Class类的实例。这个方法被声明为final的
  • findClass(String name) 查找名称为 name的类,返回的结果是java.lang.Class类的实例
  • loadClass(String name) 加载名称为 name的类,返回的结果是java.lang.Class类的实例
  • resolveClass(Class<?>) 链接指定的 Java 类

2.ClassLoader 的等级加载机制

Java默认提供的三个ClassLoader

  • BootStrap ClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该类加载器从哪些地方加载了相关的jar或class文件
    代码如下(示例):
public class BootStrapTest
{public static void main(String[] args){URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();for (int i = 0; i < urls.length; i++) {System.out.println(urls[i].toExternalForm());}}
}
C:\Program Files\Java\jre1.8.0_151\lib\resources.jar;
C:\Program Files\Java\jre1.8.0_151\lib\rt.jar;
C:\Program Files\Java\jre1.8.0_151\lib\sunrsasign.jar;
C:\Program Files\Java\jre1.8.0_151\lib\jsse.jar;
C:\Program Files\Java\jre1.8.0_151\lib\jce.jar;
C:\Program Files\Java\jre1.8.0_151\lib\charsets.jar;
C:\Program Files\Java\jre1.8.0_151\lib\jfr.jar;
C:\Program Files\Java\jre1.8.0_151\classes
  • Extension ClassLoader:称为扩展类加载器,负责加载Java的扩展类库,Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。默认加载JAVA_HOME/jre/lib/ext/目下的所有jar。
  • App ClassLoader:称为系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。

3.ClassLoader加载类的原理

https://image-static.segmentfault.com/223/583/2235836364-58e8671a820d6_fix732


三、同名类加载顺序

https://blog.csdn.net/jerry741/article/details/108771914?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

https://modouxiansheng.top/2019/06/14/%E4%B8%8D%E5%AD%A6%E6%97%A0%E6%95%B0-%E5%B7%A5%E4%BD%9C%E5%8D%8A%E5%B9%B4%E9%81%87%E5%88%B0%E6%9C%80%E5%A5%87%E8%91%A9%E7%9A%84%E9%97%AE%E9%A2%98-2019/

经过试验发现Java的获取文件夹下面的所有文件是跟操作系统的文件系统有关系的,相同的文件夹内容,在Windows中取出来,输出名字你会发现输出是经过a-z排序过的,但是在macOS或者Linux中你可以根据命令ll -fi就可以输出自然顺序,你会发现没有什么规律可言。

Linux 系统文件存储默认顺序:
取决于磁盘格式
https://unix.stackexchange.com/questions/13451/what-is-the-directory-order-of-files-in-a-directory-used-by-ls-u#comment18027_13456
https://zhuanlan.zhihu.com/p/105519189


总结

Q&A

ClassLoader 同名类加载顺序的研究相关推荐

  1. 关于 Java 同名类加载顺序问题排查方案

    排查背景 最近在生产上部署 UDF 时,遇到一个两个环境完全相同,但是一个客户端报错另一个正常的情况,经过多次调试问题终于得以解决,现将解决思路记录一下,希望能对后来者有所帮助.(生产环境不便于截图. ...

  2. Java类的加载及父类子类加载顺序

    点击 Mr.绵羊的知识星球 解锁更多优质文章. 目录 一.类的加载 1. 类加载 2. 类加载器 二.父类和子类加载顺序 1. 案例(代码) 一.类的加载 1. 类加载 当程序要使用某些类时,如果该类 ...

  3. tomcat6类加载器与类加载顺序

    tomcat6.0.32 com.dyyx.ShareUtils //返回系统当前时间 public static String now(); package com.dyyx; import jav ...

  4. Java 的类加载顺序

    Java 的类加载顺序 一.加载顺序:先父类后子类,先静态后普通 1.父类的静态成员变量初始化 2.父类的静态代码块 3.子类的静态成员变量初始化 4.子类的静态代码块 5.父类的普通成员变量初始化 ...

  5. 【Android 逆向】类加载器 ClassLoader ( 启动类加载器 | 扩展类加载器 | 应用类加载器 | 类加载的双亲委托机制 )

    文章目录 一.类加载器 二.类加载的双亲委托机制 一.类加载器 Java 虚拟机 ClassLoader 类加载器 : Bootstrap ClassLoader : 启动类加载器 , 该 加载器由 ...

  6. JAVA基础--final、static区别以及类加载顺序

    一.JAVA中final 与 static 总结 final static 修饰类 该类不可被继承 只能修饰内部类,该类不需要new,是静态加载(嵌套顶层类) 修饰接口 × × 修饰构造函数 × × ...

  7. SpringBoot控制配置类加载顺序

    1.@Configuration配置被加载进容器的方式大体上可分为3种 手动:构建ApplicationContext时由构建者手动传入,可手动控制顺序. 自动1:被@ComponentScan自动扫 ...

  8. 类加载顺序及加载过程详解

    转自: 类加载顺序及加载过程详解 下文笔者讲述类的加载顺序及加载过程的详解说明,如下所示 java创建对象的方式分为以下四种 new 反射克隆反序列化 class对象获取的方式分享 //没有完成初始化 ...

  9. Java 类加载顺序与成员变量初始化

    类加载顺序 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 ) 父类非静态代码块( 包括非静态初始化块,非静态属性 ) 父 ...

最新文章

  1. The alias LM/W3SVC/1/Root/XX already exists. Please choose a different alias
  2. 安装和配置Tomcat
  3. python中的@符号的作用
  4. cgi,fastcgi,php-cgi,php-fpm之间的关系
  5. powerpoint技巧_几乎每个PowerPoint都烂鸡蛋
  6. WEB可以调节的框架页
  7. bat 连续读取两行_Redis底层数据结构解析(BAT大厂必问)
  8. python3 urllib安装_对python3 urllib包与http包的使用详解
  9. Vue2.0 的漫长学习ing-1-5
  10. 怎么修改远程服务器的地址,怎么修改远程服务器的地址
  11. 用tbody解决div在table标签里无法隐藏某些行
  12. python 阿里云短信接口_阿里云短信接口怎么使用
  13. Ps 初学者教程,如何使用色阶滴管工具校正色偏?
  14. windows下安装linux环境
  15. SAP Fiori 的附件处理(Attachment handling)
  16. Forge 养号手机在线源安装方式;
  17. 计算机桌面没有cd驱动器,win10没有cd驱动器怎么办_win10不显示dvd驱动器的解决方法...
  18. 2015美国大学计算机科学专业排名,美国大学研究生计算机科学专业排名|2015年计算机科学专业排行榜(1/2)- 各国学校排名网...
  19. ubuntu 17.04安装为知笔记
  20. AndrewNG机器学习听课笔记(1 )——线性回归(linear regression)

热门文章

  1. 【NLP】第3章 微调 BERT 模型
  2. 计时器(视频的计时:时间码)
  3. kali Linux中文设置问题解决方案
  4. 我们仍未知道那天踩的MultipartFile file为null的大坑是为什么
  5. 项目-病例步态的分析研究跟进-使用霍尔特双参数指数平滑法来平滑关节数据的过程中的错误处理Error27error C3861: 'cvPoint': identifier not foundd
  6. 【数据分析项目实战】商铺数据加载及存储
  7. qt210 裸机ac97
  8. python批量读取grib_python读取grib2文件
  9. C语言打印所有“水仙花数”
  10. IDEA 查看类及属性的调用链