类加载条件
只有一下5种情况,才会进行类初始化
- new、get static、put static、 invoke static
- 对类进行反射调用
- 初始化一个类,但是父类还未初始化,会先初始化父类
- 指定一个执行main的类,初始化主类
- 动态语言支持
类加载器
-
启动类加载器
存放在<hava_home>\lib下的,并且是虚拟机识别的类库加载到虚拟机内存中
-
拓展类加载器
存放在<hava_home>\lib\ext下的所有类库,开发者可以直接使用
-
应用类加载器
加载用户类路径上指定的类库,开发者可以直接使用,一般这就是程序中默认的类加载器
双亲委派
双亲委派:如果一个类加载器收到了加载某个类的请求,则该类加载器并不会去加载该类,而是把这个请求委派给父类加载器,每一个层次的类加载器都是如此,因此所有的类加载请求最终都会传送到顶端的启动类加载器;只有当父类加载器在其搜索范围内无法找到所需的类,并将该结果反馈给子类加载器,子类加载器会尝试去自己加载。
例如如果子加载器不请求父加载类的意见自己擅自行动加载String类,很可能加载到黑客自己写的String类,那后果简直不敢想象。
类加载的执行过程
类加载主要由JVM负责,类加载分为加载、连接、初始化。
加载:jvm运行之前会把.class文件加载到内存,供程序使用,用到的就是类加载器ClassLoader。
连接:分为验证、准备、解析
验证:确保类加载的正确性,一般情况由javac编译的class文件是不会有问题的,但是可能有人的class文件是自己通过其他方式编译出来的,这就很有可能不符合jvm的编 译规则,这一步就是要过滤掉这部分不合法文件。
准备:为类的静态变量分配内存,并初始化为默认值。
解析:把类中的符号引用转化为直接引用。
初始化:为类的静态变量赋上真正的初始值。
java运行过程就可以分为 编译-> 类加载-> 执行