• 深入理解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");
    
  • 相关阅读:
    AOC的服务还不错
    浅谈Java、MySQL的中文排序问题
    祝cnBlogs的Blogger们新年快乐!
    GT 3.9.4以及今天的工作
    堆排序
    桶排序
    常用排序算法稳定性分析
    VS2010远程调试环境配置详解
    基数排序
    如何修改数据库的服务器名称
  • 原文地址:https://www.cnblogs.com/shanyingwufeng/p/9896602.html
Copyright © 2020-2023  润新知