如下,是牛客上的一道关于类加载的Java题目,问打印结果:
public class Test
{
public static Test t1 = new Test();
{
System.out.println("blockA");
}
static
{
System.out.println("blockB");
}
public static void main(String[] args)
{
Test t2 = new Test();
}
}
//输出结果:
//blockA
//blockB
//blockA
解题点:
1.类在加载时首先执行静态对象和静态代码块,然后是非静态对象和非静态代码块,然后是构造函数。
2.当有多个静态对象和静态代码块时,程序会按照从前到后的顺序依次执行。
3.类第一次加载时,还没有new出一个实例的时候,就可以执行静态代码块了。静态对象和静态代码块不依托于实例化对象。
本题执行顺序:
1.首先执行public static Test t1 = new Test();
因为它是静态的且在最前面。
2.静态代码块只在第一次加载类时会执行,所以当public static Test t1 = new Test();
new 了一个 Test对象时,就不会再执行静态代码块了,即只执行如下代码块,打印“blockA”。
{
System.out.println("blockA");
}
3.回到第一次加载的Test类,因为静态代码块的优先级比代码块高,且按照在程序中的先后顺序执行,所以接下来要执行如下静态代码块,打印“blockB”。此时该Test类并没有实例化对象,所以上述的打印 A 的代码块并不执行。
static
{
System.out.println("blockB");
}
4.然后执行 main 方法,在 main 方法中 new 了一个 Test 对象,由于 Test 类中的静态对象和静态代码块都已经执行过一次了,所以此时并不需要再执行静态对象和静态代码块,只需执行实例化对象时的如下代码块,打印“blockA”。
{
System.out.println("blockA");
}
由上述可得,输出结果为:blockA blockB blockA 。
如有错误或不足之处,敬请指正。