(1)验证:保证字节码文件的正确性 (2)准备:为类变量(非引用类型)分配空间和赋初始值0,准备阶段先赋0,初始化会被赋1 注意:a.finall修饰的的static属性(非引用类型)的默认值是编译期就设置好了的。 b.这个阶段不会为实例对象分配空间和赋初始值,因为类变量是分配在方法区中,而实例对象是随着java对象分配在jvm堆中的。 c.第(2)中都是“非引用类型”,是因为引用类型属性的分配空间和赋值都是在初始化中完成的。 (3)解析:将常量池中的符号引用解析为直接引用。 比如:类C定义了一个属性:Object o = new Object(); 如果未解析:则常量池中只有 "o"这个符号存在; 如果解析完成:则会讲"o"这个符号替换成实际的地址值,比如:x00987。3、初始化:初始化是指调用方法,初始是惰性的
会触发初始化的操作: (1)使用new关键字创建对象; (2)首次访问一个类的静态变量或静态方法时; (3)子类初始化时,若父类未初始化,则会触发父类的初始化; (4)子类访问父类的静态变量,只会引起父类的初始化; (5)Class.forName(初始化指定的类); (6)main方法所在的类会优先初始化; 不会触发初始的操作: (1)触发finall类型的(非引用类型)的属性,不会触发初始化; (2)loadClass方法只会加载字节码,不会触发初始化; (3)Class.forName设置初始化参数为false时,不会触发初始化; (4)类对象.class,不会触发初始化; (5)创建该对象的数组时,不会触发初始化;二、双亲委派机制 1、了解常用的类加载器
| 类加载器 | 加载的路径 | 说明 | 父类 |
|---|---|---|---|
| Bootstrap ClassLoader(启动类加载器) | JAVA_HOME/jre/lib/ | 用来加载核心库,比如包名为java,javax,sun开头的类,如java.lang.String | 无 |
| Extension ClassLoader(扩展类加载器) | JAVA_HOME/jre/lib/ext | Bootstrap ClassLoader | |
| Application ClassLoader(系统类类加载器) | 加载classpath下的类 | Extension ClassLoader |
java虚拟机加载字节码文件时是采用按需加载,也就是用到该类时才将它的字节码文件加载到内存中生成Class对象。如果一个类加载器收到了加载请求,他自己是不会先去加载的,而是先委托给父类加载,如果父类不负责该文件加载则父类会委托回给子类加载。
3、双亲委派机制的好处与作用(1)保证类不会重复加载
(2)保证了沙箱安全机制。比如我们自定义来java.lang包,并新建了一个名为Demo的类,此时加载这个类会通过双亲委派机制,委派给启动类加载器加载,这时加载就会报错,因为是不允许在核心包下自定义新的类的。这样就保护来java核心包下的代码的安全性。
(1)包名和类名必须完全相同
(2)使用的类加载器必须是同一个,类加载器不同,加载的实例就会不同



