这里看到一篇比较好的文章:http://www.infoq.com/cn/articles/cf-Java-class-loader
这里只是针对什么时候会触发java类的初始化(注意:这里不是说的实例化)进行讨论:
除了文章中提到的5点:
- 创建一个Java类的实例。如
MyClass obj = new MyClass()
- 调用一个Java类中的静态方法。如
MyClass.sayHello()
- 给Java类或接口中声明的静态域赋值。如
MyClass.value = 10
- 访问Java类或接口中声明的静态域,并且该域不是常值变量。如
int value = MyClass.value
- 在顶层Java类中执行assert语句。
- 通过Java反射API也可能造成类和接口的初始化
这里我想说明一下final static修饰的字段(情况一共分为3种):
第一种(类不会被初始化):
public final static String a = "abc";
第二种(类会被初始化):
public final static String a; static{ a = "abc" }
第三种(类会被初始化):
public final static String a = new String("abc");
这里还是借用文章中的一句话:
"非常量赋值的final域以及静态块中初始化的final域被访问都会导致类的初始化;其他常量赋值的final域被访问则不是,我估计着它会在类的链接阶段就被初始化了。"
下面是测试的代码:
public class TestClassLoader { public final static String a = "abc"; //public final static String a = new String("abc"); static { //a = "abc"; System.out.println("类被初始化了"); } }
public class Test { public static void main(String[] args) { System.out.println(TestClassLoader.a); } }