zoukankan      html  css  js  c++  java
  • 深入理解Java程序执行顺序

    下面将从一道阿里巴巴试题详细分析Java程序执行顺序。

    阿里巴巴试题

    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;
    	public int j = print("j");
    
    	{
    		print("构造块");
    	}
    
    	static {
    		print("静态块");
    	}
    
    	public Test(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 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、五个成员变量被 static 修饰,即为类 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;
    

    2、j 为实例成员变量,只在类被实例化的过程被加载。

    public int j = print("j");
    

    3、实例化代码块,在类被实例化的过程中执行。

    {
    	print("构造块");
    }
    

    4、静态代码块,在类被加载、初始化的过程中执行。

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

    5、静态方法

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

    类加载过程分析

    加载过程:执行 main 方法时,先加载所在类,声明静态变量,并初始化静态变量,执行静态代码块(按照出现顺序执行)。

    1、初始化到 t1 的时候,暂停类加载,先进行类实例化,此时 k 已经初始化为 0,而 i 和 n 都未初始化,系统默认为 0。

    public static int k = 0;
    public static Test t1 = new Test("t1");
    

    2、因为 j 为实例变量,会在类实例化的时候被初始化,所以先执行 print() 方法:

    public int j = print("j");
    
    

    然后执行代码块,print("构造块"):

    {
        print("构造块");
    }
    

    执行完代码块后,执行构造方法:

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

    3、t2 和 t1 的加载顺序完全一样。
    4、初始化到 i 的时候,执行 print("i") 方法。

    public static int i = print("i");
    

    5、静态属性加载完成后,执行 new Test("init") 方法,调用构造方法。

    new Test("init");
    
  • 相关阅读:
    HDU5618 Jam's problem again
    BZOJ2002弹飞绵羊
    树剖模板
    点分治模板题
    c++ 读入优化、输出优化模板
    牛客网练习赛44-B(快速幂+模拟)
    poj2912(带权并查集+枚举)
    ucore-lab1-练习3report
    poj2492(带权并查集)
    poj1984(带权并查集)
  • 原文地址:https://www.cnblogs.com/shanyingwufeng/p/9896602.html
Copyright © 2011-2022 走看看