以下举例说明Java类何时需要进行初始化:
使用new实例化对象时:
public class MyClass {
public static void main(String[] args) {
// 创建MyClass的实例对象,此时MyClass会被初始化
MyClass obj = new MyClass();
}
}
读取或者设置一个类的静态字段或方法时:
public class MyClass {
// 定义一个静态字段,此时MyClass会被初始化
public static String name = "MyClass";
// 定义一个静态方法,此时MyClass会被初始化
public static void printName() {
System.out.println(name);
}
}
反射调用时,例如Class.forName("com.xxx.MyTest"):
public class MyClass {
static {
System.out.println("MyClass 被初始化");
}
}
public class MyTest {
public static void main(String[] args) throws ClassNotFoundException {
// 加载MyClass类,此时MyClass会被初始化
Class.forName("MyClass");
}
}
初始化一个类的子类,会首先初始化子类的父类:
public class Parent {
static {
System.out.println("Parent 被初始化");
}
}
public class Child extends Parent {
static {
System.out.println("Child 被初始化");
}
public static void main(String[] args) {
// 创建Child的实例对象,Child和Parent都会被初始化
Child obj = new Child();
}
}
Java虚拟机启动时标明的启动类:
public class MyStartClass {
public static void main(String[] args) {
// MyStartClass被当做启动类,此时会被初始化
System.out.println("Hello, World!");
}
}
在使用Classloader类的loadClass()方法来加载类时,该类只进行加载阶段,而不会经历初始化阶段:
public class MyClassLoader {
public static void main(String[] args) throws ClassNotFoundException {
// 调用ClassLoader.loadClass()方法加载MyClass类,并不会被初始化
ClassLoader cl = MyClass.class.getClassLoader();
Class<?> cls = cl.loadClass("MyClass");
}
}
运行main方法,main方法所在类会被加载:
public class MyClass {
public static void main(String[] args) {
System.out.println("MyClass main 方法被调用");
}
}
JDK8 之后,接口中存在default方法,这个接口的实现类初始化时,接口会在其之前进行初始化:
public interface MyInterface {
default void printName() {
System.out.println("MyInterface");
}
}
public class MyImpl implements MyInterface {
static {
System.out.println("MyImpl 被初始化");
}
public static void main(String[] args) {
// 创建MyImpl的实例对象,MyImpl和MyInterface都会被初始化
MyImpl obj = new MyImpl();
obj.printName(); // 输出:MyInterface
}
}