jvm加载类的流程
1、加载(将对应的.class字节码文件加载到对应的类到内存)
2、验证(校验相应的.class是否完全符合jvm规范)
3、准备(需要关注的,因为给类分配了内存空间,类变量也分配好内存空间,并给默认值)
给类变量分配内存空间,并赋值一个初始值
4、解析(解析符号,并关联到具体的对象的真正的内存地址)
将符号引用替换为直接引用
符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《java虚拟机规范》的class文件格式中。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄
5、初始化
执行变量的赋值逻辑、
执行静态代码块中的逻辑
什么时候会初始化一个类?
比如new Object()->触发加载到初始化的全过程
或者包含main方法的主类,必须立马初始化,如果父类还没有初始化,需要先初始化父类。
6、使用
7、卸载
类加载器的概念
1、启动类加载器 ,bootstrap classLoader
主要加载java目录下的核心类(jdk安装目录下的lib)
2、扩展类加载器,extension classloader
主要加载扩展目录下的jar(jdk安装目录下的lib\ext)
3、应用程序类加载器,Application ClassLoader
用于加载classpath环境变量所指定的路径的类,简单的理解,就是加载你写的java代码
4、自定义类加载器,根据自己的需求加载类
比如加载的类是为了防止别人反编译而加密过的class文件
为了防止别人反编译源码,可以对class文件进行加密,然后用自定义类加载器进行解密
什么是双亲委派机制?
启动类加载器:lib下的jar
扩展类加载器:lib\ext下的jar
应用程序加载器:classpath下的jar
自定义类加载器:自定义路径下的jar
如果你的应用程序加载器需要加载一个类,它不会立即去加载对应的类,它会先委派自己的双亲去加载类,最终传到启动类加载器上,启动类加载器判断是否能加载到该类,如果没有,让扩展类加载器去加载,如果也没有加载到,让应用程序去加载(先让父亲去加载,不行在让儿子去加载)
为什么要使用双亲委派机制?
任意一个jar中,都有可能出现相关的package和class名,所以如果没有双亲委派,那么比如自己写了一个string,lib下也有一个String,那么使用应用程序加载器加载的string和启动类加载器加载的string就不是同一个类,所以任何类的加载使用这个流程,去确保在一个运行系统中,相同的package和class加载的是相同的类。