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