我们知道,当我们用到一个类时,需要先将类加载进去,类被加载进去的时候类里的所有静态成员变量是被自动执行的,比如说有这么一个类:
public class StaticEnforce {
public static int i = 9;
public static StaticEnforce benforced = new StaticEnforce(1) {
public void enforce1() {
System.out.println("the static statement has been enforced");
}
};
public void enforce1() {
System.out.println("the constructor has been enforced");
}
public StaticEnforce(int i) {
enforce1();
}
}
当我们执行Class.forName(“StaticEnforce”)语句的时候,类里面的静态成员变量i 和benforced 会被自动赋值,9会被赋值给i , new StaticEnforce(1) 的执行结果会被赋值给benforced ,new StaticEnforce(1)是一个内部类,它的构造方法会自动调用已经被重写了的enforce1()方法,而enforce1()方法的执行结果就是在屏幕上打印出the static statement has been enforced语句,因为类的加载只被执行一次便永久存在于内存中,所有类里面的静态成员变量的赋值也只被执行一次,比如,我们调用如下语句:
int sf0 = StaticEnforce.i;
System.out.println("类已被加载进内存");
StaticEnforce sf = StaticEnforce.benforced;
System.out.println("静态代码块只被执行一次");
newStaticEnforce(1990);
当程序执行到第一句的时候类会被被加载进内存,此时类中的所有的静态成员变量都会被赋值,benforced 也会毫不例外地会被赋值,因此System.out.println("the static statement has been enforced")语句会被自动执行,然后打印出类已被加载进内存,执行到第三句的时候由于类中成员变量已被初始化(或叫赋值),所以相当于重复执行了一次赋值操作,接着执行第四句,打印出静态代码块只被执行一次,最后一条代码调用类中的构造方法,因此打印出the constructor has been enforced。
有了上面的分析,我们再来看JAVA里的枚举类型,枚举类型实际上是一个类,我们定义如下枚举类型:
public enum WeekDay{
SUN(1),MON(2),TUS(3),WED,THU,FRI,SAT;
private WeekDay(){System.out.println("First day");}
private WeekDay(int day){System.out.println("second day"+day);}
}
类中定义了两个构造方法,当我们执行WeekDay WeekDayFri = WeekDay.FRI这条语句的时候,类会自动被发现并被加载进内存,并且对类中的所有静态变量初始化,SUN(1),MON(2),TUS(3),WED,THU,FRI,SAT这些变量都会被初始化,但这些变量被初始化时调用的类中的构造方法是不同的SUN(1),MON(2),TUS(3),调用的是类中的第二个构造方法,WED,THU,FRI,SAT,调用的是类中的第一个构造方法,因此执行结果是打印出三行First day,四行second day,并得到WeekDay.FRI的引用变量。