先来一段代码
public class AboutClassLoad {
private static int k = 1;
private static AboutClassLoad t1 = new AboutClassLoad("t1");
private static AboutClassLoad t2 = new AboutClassLoad("t2");
private static int i = print("i");
private static int n = 99;
static {
print("静态块");
}
private int j = print("j");
{
print("构造块");
}
public AboutClassLoad(String str) {
System.out.println((k++)+":"+str+" i="+i+" n="+n);
++i;
++n;
}
public static int print(String str) {
System.out.println((k++)+":"+str+" i="+i+" n ="+n);
++n;
return ++i;
}
public static void main(String[] args) {
new AboutClassLoad("init");
}
}
我们来一起分析一下:
首先先加载类中的静态变量,因为这些静态变量不需要实例化对象就可以通过类名直接调用因此首先先加载第一行
private static int k = 1;
接着加载第二行,第二行用本类定义了一个变量,这个时候会在加载这个类中的非静态成员变量,因此,
加载这一行private int j = print("j"); 这个时候会调用print方法
于是输出 1:j i=0 n=0
接着实例化对象new AboutClassLoad("t1"); 这时会调用构造代码块,也就是
{
print("构造块");
}
于是输出 2:构造块 i=1 n =1
构造代码块是实例化一个对象就会调用一次,调用完之后会调用类的构造方法public AboutClassLoad(String str)
于是接着输出 3:t1 i=2 n=2
同理 ,private static AboutClassLoad t2 = new AboutClassLoad("t2");的分析也和上面一样,控制台上接着输出
4:j i=3 n =3
5:构造块 i=4 n =4
6:t2 i=5 n=5
接着继续加载静态变量private static int i = print("i");调用print方法输出
7:i i=6 n =6
接着加载最后一个静态变量 n;
到这里静态变量就加载完了,
接着就是加载静态代码块
static {
print("静态块");
}
并且调用print方法,这个时候调用的n就是静态变量n,因此输出的n为99,于是输出 8:静态块 i=7 n =99
接着进入主方法,为实例化的的对象,分配空间,此时又调用private int j = print("j"),
于是输出 9:j i=8 n =100
接着调用构造代码快的内容
最后调用构造方法
于是,会输出以下内容:
程序的输出结果如下
这里我们可以总结一下:
关于类的加载,首先先加载静态变量,接着加载静态代码块,接着加载主函数里面的内容
关于实例化对象,首先会在堆中分配内存,接着初始化属性的值,如果有构造代码块就调用构造代码块,然后调用构造函数。