虚拟机规范严格规定了有且只有四种情况必须立即对类进行初始化:
1. 遇到new、getstatic、putstatic、invokestatic这四条字节码指令时,
如果类还没有进行过初始化,则需要先触发其初始化。
生成这四条指令最常见的Java代码场景是:
使用new关键字实例化对象时、
读取一个类的静态字段(static)时(被static修饰又被final修饰的,已在编译期把结果放入常量池的静态字段除外)
设置一个类的静态字段(static)时(被static修饰又被final修饰的,已在编译期把结果放入常量池的静态字段除外)
以及调用一个类的静态方法时。
2. 使用Java.lang.refect包的方法对类进行反射调用时,如果类还没有进行过初始化,则需要先触发其初始化。
3. 当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
4. 当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先执行该主类。

对于静态字段,只有直接定义这个字段的类才会被初始化,因此,通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化

接口初始化与类初始化区别:
当一个类在初始化时,要求其父类全部已经初始化过了,
但是一个接口在初始化时,并不要求其父接口全部都完成了初始化,只有在真正使用到父接口的时候(如引用接口中定义的常量)
才会初始化该父接口。
调用类中的static final常量时并不会触发该类的初始化,但是调用接口中的static final常量时便会触发该接口的初始化

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐