初始化有效地实现了尽可能的惰性。仅使用.class语法来获得对类的引用不会引发初始化。但是为了产生Class引用,Class.forName()
立即就进行了初始化
如果一个static final值是编译期常量,那么这个值就不需要对类进行初始化就能获取,但是如果将一个域设置成static和final的,还不足
以确保这种行为,对它的访问就会强制进行类的初始化,因为他不是一个编译期常量
如果一个static域不是final的,那么在对他访问时,总是要求她在被读取之前,要先进行链接(为这个域分配存储空间)和初始化(初始化
该存储空间)
为了使用类而做的准备工作包含三个步骤:
1.加载,这是由类加载器执行的。该步骤将查找字节码(通常在classpath所指定的路径中查找,但这并非必须的),并从这些字节码中创建一个Class对象。
2.链接,在链接阶段将验证类的字节码,为静态域分配存储空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用。
3.初始化,如果该类具有超类,则对其进行初始化,初始化静态域和静态初始化块。
初始化被延迟到对静态方法(构造器隐式地是静态的)或者非常数静态域进行首次引用时才执行。
/**
*
*/
package com.runtech;
import java.util.Random;
public class Demo002 {
public static Random random = new Random(47);
public static void main(String[] args) {
Class c1 = Initable1.class;//不会初始化
System.out.println(Initable1.staticFinal01);//编译期常量
System.out.println(Initable1.staticFinal02);//强制类的初始化,非编译期常量
System.out.println("-----------------------------------");
try {
Class c2 = Class.forName("com.runtech.Initable1");//直接就初始化了
System.out.println(Initable2.staticFinal01);
System.out.println(Initable2.staticFinal02);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("-----------------------------------");
Class c3 = Initable3.class;
System.out.println(Initable3.staticFinal01);//非编译期常量
System.out.println(Initable3.staticFinal02);
System.out.println("-----------------------------------");
new Initable2();
System.out.println(Initable2.staticFinal01);
System.out.println(Initable2.staticFinal02);
}
}
class Initable1 {
static final int staticFinal01 = 47;
static final int staticFinal02 = Demo002.random.nextInt(1000);
static {System.out.println("Initable1 static");}
public Initable1() {
System.out.println("Initable1 Constructor");
}
}
class Initable2 {
static int staticFinal01 = 12;
static final int staticFinal02 = Demo002.random.nextInt(1000);
static {System.out.println("Initable2 static");}
public Initable2() {
System.out.println("Initable2 Constructor");
}
}
class Initable3 {
static int staticFinal01 = 12;
static final int staticFinal02 = Demo002.random.nextInt(1000);
static {System.out.println("Initable3 static");}
public Initable3() {
System.out.println("Initable3 Constructor");
}
}
输出 :
47
Initable1 static
258
-----------------------------------
Initable2 static
12
555
-----------------------------------
Initable3 static
12
693
-----------------------------------
Initable2 Constructor
12
555