java虚拟机通过装载、连接和初始化一个java类型,使该类型可以被一个正在运行的java程序所使用。
装载就是把二进制形式的java类型读入java虚拟机中;
连接就是把已经读入虚拟机的二进制形式的类型数据合并到虚拟机的运行时状态中去,连接阶段分为3个子步骤--验证、准备、解析。
之后就时初始化。
java虚拟机实现必须在每个类或接口首次主动使用时初始化。
下面这六种情形符合主动使用的要求:
1 、当创建某个类的新实例时(或者通过在字节码中执行new指令;或者通过不明确的创建、反射、克隆或者反序列化)。
2、当调用某的类的静态方法时(即在字节码中执行invokestatic指令时)。
3、当使用某个类或接口的静态字段,或者对该字段赋值时(即在字节码中,执行getstatic或putstatic指令时),用final修饰的静态字段除外,它被初始化为一个编译时的常量表达式。
4、当调用api中的某些反射方法时,比如类class中的方法或者java.lang.reflect包中的类方法。
5、当初始化某个类的子类时,(某个类初始化时,要求它的超类已经被初始化了)
6、当虚拟机启动某个被表明为启动类的类(即含有main方法的那个类)
注意:
使用一个非常量的静态字段只有当类或者接口的确声明了这个字段的时候才是主动调用;
类中声明的字段可能会被子类引用;接口中声明的字段可能会被子接口或者实现了这个接口的类引用。对于子类、子接口和实现了接口的类来说,就是被动调用--使用它们并不会触发它们的初始化。
如果程序不在引用某类型,那么这个类型就无法再对未来的计算过程产生影响。类型变成不可触及的,而且可以被垃圾收集。
装载就是把二进制形式的java类型读入java虚拟机中;
连接就是把已经读入虚拟机的二进制形式的类型数据合并到虚拟机的运行时状态中去,连接阶段分为3个子步骤--验证、准备、解析。
之后就时初始化。
java虚拟机实现必须在每个类或接口首次主动使用时初始化。
下面这六种情形符合主动使用的要求:
1 、当创建某个类的新实例时(或者通过在字节码中执行new指令;或者通过不明确的创建、反射、克隆或者反序列化)。
2、当调用某的类的静态方法时(即在字节码中执行invokestatic指令时)。
3、当使用某个类或接口的静态字段,或者对该字段赋值时(即在字节码中,执行getstatic或putstatic指令时),用final修饰的静态字段除外,它被初始化为一个编译时的常量表达式。
4、当调用api中的某些反射方法时,比如类class中的方法或者java.lang.reflect包中的类方法。
5、当初始化某个类的子类时,(某个类初始化时,要求它的超类已经被初始化了)
6、当虚拟机启动某个被表明为启动类的类(即含有main方法的那个类)
注意:
使用一个非常量的静态字段只有当类或者接口的确声明了这个字段的时候才是主动调用;
类中声明的字段可能会被子类引用;接口中声明的字段可能会被子接口或者实现了这个接口的类引用。对于子类、子接口和实现了接口的类来说,就是被动调用--使用它们并不会触发它们的初始化。
如果程序不在引用某类型,那么这个类型就无法再对未来的计算过程产生影响。类型变成不可触及的,而且可以被垃圾收集。