public class Test {
static {
System.out.println("***");
}
public static final String a = "sss";
//final static double a = Math.random();
}
public class Test1 {
public static void main(String[] args) {
System.out.println(Test.a);
}
}
输出为: sss
下面这六种情形符合主动使用的要求:
1 、当创建某个类的新实例时(或者通过在字节码中执行new指令;或者通过不明确的创建、反射、克隆或者反序列化)。
2、当调用某的类的静态方法时(即在字节码中执行invokestatic指令时)。
3、当使用某个类或接口的静态字段,或者对该字段赋值时(即在字节码中,执行getstatic或putstatic指令时),用final修饰的静态字段除外,它被初始化为一个编译时的常量表达式。
类的成员变量在执行期间才能得到值的,访问此成员也可是对此类的主动调用。比如:final static double a = Math.random();
4、当调用api中的某些反射方法时,比如类class中的方法或者java.lang.reflect包中的类方法。
5、当初始化某个类的子类时,(某个类初始化时,要求它的超类已经被初始化了)
6、当虚拟机启动某个被表明为启动类的类(即含有main方法的那个类)
java虚拟机实现必须在每个类或接口首次主动使用时初始化。
使用一个非常量的静态字段只有当类或者接口的确声明了这个字段的时候才是主动调用;
类中声明的字段可能会被子类引用;接口中声明的字段可能会被子接口或者实现了这个接口的类引用。对于子类、子接口和实现了接口的类来说,就是被动调用--使用它们并不会触发它们的初始化。