++2016.7.17
++by side @java-加载顺序(2)
==================================
关于JAVA-加载顺序(2)
下面是阿里巴巴的面试题:
//阿里巴巴面试题
//输出打印结果
public class AlibabaInterview implements Cloneable
{
public static int k = 0;
public static AlibabaInterview t1 = new AlibabaInterview("t1");
public static AlibabaInterview t2 = new AlibabaInterview("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造代码块");
}
static {
print("静态代码块");
}
public AlibabaInterview(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) {
}
}
解决本类问题需注意以下几点:
- 类属性初始化时虚拟机是不会声明属性的同时赋值的,它会把所有属性和方法全部声明完了再从头按代码顺序赋值。
类加载过程(静态属性、静态方法声明-----静态属性赋值、静态块)注意先父类后子类。
- 实例化过程(普通属性、普通方法声明-----普通属性赋值、构造块----构造方法中的代码)也是先父类后子类
- 如果在类加载过程中调用了实例化过程(如new了本类对象),则会暂停类加载过程先执行实例化过程,执行完毕再回到类加载过程
- 实例化t1的时候,会进入实例化过程:普通属性j,构造快,然后才是构造方法 (可以理解为j和构造快为t1自己的东西,必须先分配好)
t2同理,等静态成员初始化结束后,静态块。
*/
解题步骤:
- 找到main()方法以main()方法为入口加载所在的类(有父类的先加载父类)
- 在加载的过程中,先声明所有的静态成员,再依次进行赋值此时 k=0
- 接着到了 t1=new ... 此时中断 类的加载 开始 t1的实例化,在t1的实例化过程中,先声明所有的非静态的成员,再进行赋值
- 此时遇到了 public int j = print("j"); 先执行print("j");打印 [1: j i=0 n=0] (i,n,默认为0 此时k=1,i=1,n=1,j=1).
- 接着是遇到 print("构造代码块");打印 [2: 构造代码块 i=1 n=1](此时k=2,i=2,n=2,)
- 然后就是构造方法 打印 [3: t1 i=2 n=2](此时k=3,i=3,n=3,)。
- 那么t1的实例化到此结束,开始类的加载。然而不幸的是又遇到了t2的实例化 同理依次打印打印
[4: j i=3 n=3] (此时k=4,i=4,n=4,)
[5: 构造代码块 i=4 n=4](此时k=5,i=5,n=5,)
[6: t1 i=5 n=5](此时k=6,i=6,n=6,)
- 一直到t2的实例化结束,又开始类的加载。遇到i = print("i");
- 同理 打印[7: i i=6 n=6] (此时k=7,i=7,n=7,)接着是 n=99
- 最后打印[8: 静态代码块 i=7 n=99](此时k=8,i=8,n=100,)
- 到此类的加载完毕,开始执行main里方法语句(本题无)。
打印结果如下:
打印结果==================================
@小怪兽
ps:因作者能力有限,有错误的地方请见谅
网友评论