杨七七,你比我厉害!!!
但是我可以比你更你厉害!!!怒刷!!!
public static Test t1 = new Test();
public static Test t2 = new Test();
{
System.out.println("构造块");
}
static
{
System.out.println("静态块");
}
public static void main(String[] args)
{
Test t = new Test();
}
输出:
构造块
构造块
静态块
//前三个是初始化类后的输出,后面的是main方法中new的输出!!!
构造块
解答
杨七七问我这个题,我出错了。哎MD,没有仔细分析。。。
关键点:处于类的初始化过程时,不会再触发类的初始化!!!
详细分析:
在main方法里面new Test的时候,经历了如下过程:
1.类的加载:
- 该步骤执行完成后,静态成员变量已经被初始化成了默认值。如boolen为false,int为0,类变量赋值为null。
- 静态成员方法已经被加载到方法区内存中了,可以调用执行!!!
2.类的初始化:
- 这个阶段会执行静态代码块、初始化静态成员变量赋值为程序员设定的目标值。如果像上面的特殊情况,在初始化类的过程中,实例化了本类,那么这个实例化的过程还是会按照约定进行,比如执行非静态代码块,初始化非静态成员变量,初始化非静态成员变量是一步到位,直接初始化为程序员赋的值,而不会有中间值之说。
- 在上面这种特殊情况里,本来就是处在初始化的过程中实例化本类,所以就不会像递归那样再进入第二层初始化的。
该例子类的初始化执行完毕后就会输出:
构造块
构造块
静态块
3.最后就是main中类的实例化
- 进行到这个阶段时,类的初始化就已经完成了,最后进行实例化!!
该步骤执行完毕后就会输出:
构造块
总结:
- 静态代码块,静态成员变量只初始化一次。在类的初始化过程中执行!!!
- 非静态代码块和非静态成员变量在实例化过程中被执行,每次实例化都会执行!!!
- 类的初始化和类的实例化,这两个过程是两个互相独立的,两个过程所要执行的任务也是分开的!!!
- 类的初始化和类的实例化执行顺序也是不一定的,比如:类实例化完成时,类的初始化不一定已经完成了。在类初始化过程中,可以实例化本类!!!
再来一个
这是笔者想出的一个,旨在帮读者测试一下是否真的明白了!!!
public static Test t1 = new Test();
public static Test t2 = new Test();
{
System.out.println("构造块");
showStaticMethod();
if(t1!=null){
t1.show();
}
System.out.println(number);
}
static {
System.out.println("静态块");
}
private static int number=10+10;
public static void showStaticMethod(){
System.out.println("StaticMethod Executed!!");
}
public void show(){
System.out.println("杨七七!!!");
}
public static void main(String[] args) {
Test t = new Test();
}
输出:
构造块
StaticMethod Executed!!
0
构造块
StaticMethod Executed!!
杨七七!!!
0
静态块
构造块
StaticMethod Executed!!
杨七七!!!
20