Java中类的加载过程
类加载的过程:
1、加载:通过类加载器把字节码加载到方法区中,生成一个对应的Class对象。
2、链接:分配内存,连接引用。
3、初始化:先初始化父类,在初始化自己。(执行类的构造器:< clinit( ) > 方法)
1、加载
类加载器( abstract class ClassLoader)
引导类加载器:BootClassLoader。用来加载Java的核心库。用C语言实现,它并未实现java.lang.ClassLoader。
扩展类加载器:ExtClassLoader,它继承了BootClassLoader。用来加载Java扩展库。
应用程序加载器:AppClassLoader,它继承了ExtClassLoader。根据路径进行加载类。
以上采用代理模式加载(双亲委派机制),在加载时会先由父类进行加载,父类加载失败再自己加载,例如:
我需要加载一个用户自己编写的java.lang.String类,AppClassLoader会丢给ExtClassLoader加载,ExtClassLoader会丢给BootClassLoader加载。显然这个类会在父类加载器中加载,也就是说用户自己编写的String将不会被加载。
常用方法:
ClassLoader.getSystemClassLoader() 获取系统使用的类加载器
getParent() 获取此加载器的父类加载器。
loadClass(String name) 加载名称为name的类,返回Class对象。
findClass(Stirng name) 查找名称为name的类,返回Class对象。
可以通过继承ClassLoader自定义类加载器自定义类加载器。
2、链接
1、验证:验证加载的类符合JVM规范,可以加载。
2、准备:为static变量分配内存(方法区),赋初始值。
3、解析:常量池内的符号引用替换为直接引用。
3、初始化
1、初始化一个类,如果其父类未初始化,会先初始化它的父类。
2、初始化过程是执行类的构造器:< clinit( ) > 方法,此方法由编译器自动收集的“类中所有静态变量的赋值语句+静态块”得到,编译器的收集顺序由代码的出现顺序决定,所以静态块只能访问前面的静态变量,不能访问后面的静态变量。
不会导致类的初始化:1、引用类中的常量。2、通过数组定义类的引用。
jvm简易结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步