java中类的加载与实例化顺序

程序实例化与类加载机制解析
首先来看一段程序,通过它的输出来分析类的加载以及实例化的机制。

public class T implements Cloneable {
public static int k = 0;
public static T t1 = new T("t1");
public static T t2 = new T("t2");
public static int i = print("i");
public static int n = 99;

public int j = print("j");

{
print("构造块");
}

static {
print("静态块");
}

public T(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
++i;
}

public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}

public static void main(String[] args) {

}
}

输出:
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

首先从main函数进入程序,类中的静态成员会被先加载,加载的时候,JVM首先将类中静态属性的声明和静态方法的声明加载到内存中(方法区中),然后将静态属性赋值,之后执行静态块中的代码。如果在类加载的时候遇到实例化的情况,首先加载普通属性的声明,然后普通方法的声明,之后是普通属性赋值,执行构造块代码,最后执行构造函数中的代码。如果有继承关系,父类优先于子类。这是基本的加载顺序。
接下来我们逐行来分析。首先加载类中的静态属性声明,(static )int k, T t1, T t2, int i, int n,[i][b](只有声明还没有赋值)[/b][/i],然后加载静态方法声明static int print(String str) {}。之后对静态属性赋值,首先加载k = 1;[color=blue]当加载到t1 = new T("t1")时,这是实例化的过程,这时类暂时不加载。按照上面所说的,实例化的时候首先加载类中的普通成员声明 int j, 然后是普通方法声明,public T(String str){},之后对普通属性赋值,这时j = print("j"), 就调用了public static int print(String str){} 方法,这时的i和n还没有被赋值,仅仅是JVM在声明时给它分配的初始值,都为0。因此这时的输出为[i]1:j i=0 n=0[/i]。这是普通属性的赋值,接下来是构造块的执行因此有了第二行输出:[i]2:构造块 i=1 n=1[/i],最后是构造函数执行,有了第三行输出:[i]3:t1 i=2 n=2[/i]。到现在t1的实例化过程结束,接着进行类的加载。[/color] 接下来对t2进行复制,也是一个实例化的过程,和上面蓝色字体描述的一样, 于是就有了4,5,6三行输出。再下面对static int i进行复制 i = print("i") 因此有了第七行输出。接下来对public static n 进行赋值, n = 99。此时静态属性赋值全部结束,最后加载静态块中的内容,print("静态块"), 因为这时的n已经被赋值了,因此最后的输出为:8:静态块 i=7 n=99
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值