题目:
public class Test{
public static int k = 0;
public static Test t1 = new Test("t1");
public static Test t2 = new Test("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j");
{
print("构造代码块");
}
static{
print("静态代码块");
}
public Test(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++i;
++n;
}
private static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return++i;
}
public static void main(String[] args) {
Test t = new Test("init");
}
}
输出结果为:
1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102
分析:
1、声明静态变量,并赋值为变量类型默认值:k=0 t1=null t2=null i=0 n=0。
2、初始化静态变量:k=0。
3、初始化静态变量:t1=new Test("t1")。此处实例化Test类时,会先定义非静态变量:a=0 j=0,紧接着,初始化非静态变量:a=0 j=print("j"),此处对j初始化时调用print方法,输出之前,k先自增,k=1,而后输出:1:j i=0 n=0,同时,i=1 n=1。回到执行t1=new Test("t1"),调用Test构造方法前,先执行构造代码块,构造代码块调用print方法,输出之前,k先自增,k=2,而后输出:2:构造块 i=1 n=1 ,同时,i=2 n=2。继续执行t1=new Test("t1"),调用Test构造方法,输出之前,k先自增,k=3,而后输出:3:t1 i=2 n=2,同时,i=3 n=3。
4、初始化静态变量:t2=new Test("t2"),步骤同3。此处实例化Test类时,会先定义非静态变量:a=0 j=0,紧接着,初始化非静态变量:a=0 j=print("j"),此处对j初始化时调用print方法,输出之前,k先自增,k=4,而后输出:4:j i=3 n=3,同时,i=4 n=4。回到执行t2=new Test("t2"),调用Test构造方法前,先执行构造代码块,构造代码块调用print方法,输出之前,k先自增,k=5,而后输出:5:构造块 i=4 n=4,同时i=5 n=5。继续执行t2=new Test("t2"),调用Test构造方法,输出之前,k先自增,k=6,而后输出:6:t2 i=5 n=5,同时i=5 n=5。
5、初始化静态变量:i=print("i")。调用print方法,输出之前,k先自增,k=7,而后输出:7:i i=6 n=6,同时i=7 n=7。
6、初始化静态变量:n=99。
7、按照声明顺序,执行静态代码块:静态代码块调用print方法,输出之前,k先自增,k=8,而后输出:8:静态块 i=7 n=99,同时,i=8 n=100。
8、此时,静态变量初始化和静态代码块执行已完成。继续声明非静态变量,并赋值为变量类型默认值:a=0 j=0。
9、初始化非静态变量:a=0。
10、初始化非静态变量:j=print("j")。此处对j初始化时调用print方法,输出之前,k先自增,k=9,而后输出:9:j i=8 n=100,同时,i=9 n=101。
11、此时,Test的加载已完成,继续执行Main方法中Test t=new Test("init")。调用Test构造方法前,先执行构造代码块,构造代码块调用print方法,输出之前,k先自增,k=10,而后输出:10:构造块 i=9 n=101,同时i=10 n=102。继续执行t=new Test("init"),调用Test构造方法,输出之前,k先自增,k=11,而后输出:11:init i=10 n=102,同时i=11 n=103。
总结:
如存在类的继承:
1、先进行父类静态变量初始化和静态代码块执行,两者的执行顺序取决于声明的顺序。
2、再进行子类静态变量初始化和静态代码块执行,两者的执行顺序取决于声明的顺序。
3、再进行父类非静态变量初始化和非静态代码块执行,两者的执行顺序取决于声明的顺序。
4、再进行父类构造方法执行。
5、再进行子类非静态变量初始化和非静态代码块执行,两者的执行顺序取决于声明的顺序。
6、再进行子类构造方法执行。
7、静态代码块只在类加载时执行一次,构造代码块在每次调用类的构造方法实例化时都会执行一次。
以上,概括为:先子类后父类,先静态后非静态,先属性后方法,先声明后赋值。
网友评论