java程序执行顺序理解

 

public class StaticTest
{
    public static int k = 0;
    public static StaticTest t1 = new StaticTest("t1");
    public static StaticTest t2 = new StaticTest("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");
    {
        print("构造块");
    }
    static
    {
        print("静态块");
    }
    public StaticTest(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);
        ++i;
        return ++n;
    }
    public static void main(String[] args)
    {
        StaticTest t = new StaticTest("init");
    }
}

1. 首先加载类,加载类过程中对于定义的静态字段分配内存空间,也是在方法区中,并进行零初始化,即数字类型初始化为0,boolean初始化为false,引用类型初始化为null等。这也就是为什么刚开始i=0,n=0

2. 执行第一句public static int k = 0;对k进行赋值

3. 执行第二句public static StaticTest t1 = new StaticTest("t1");这是定义了一个类的静态对象,在t1对象初始化时先执行非静态方法或者非静态常量,顺序执行,接着运行构造参数。意思是当声明了对象名后,我的类有了一个对象,就默认调用了类中定义的非静态的变量     和方法,依次进行;所以这时就会调用public int j = print("j");

   此时会调用print方法,其中++i,i=1=i+1; 返回值++n,n=1=n+1;j=1,k=1.

   打印  1:j i=0 n=0

   然后执行非静态块print("构造块");调用print函数

   打印  2:构造块 i=1 n=1

   没有了非静态的方法,块或常量后,之后会对t1初始化,执行类的构造函数public StaticTest(String str);

   打印  3:t1 i=2 n=2

4. 执行第三句public static StaticTest t2 = new StaticTest("t2");和上面一步的分析方法一样。

扫描二维码关注公众号,回复: 3955573 查看本文章

   依次打印

          4:j i=3 n=3

          5:构造块 i=4 n=4

          6:t2 i=5 n=5

5. 执行第四句public static int i = print("i");调用print方法

    打印  7:i i=6 n=6

6. 执行第五句public static int n = 99;至此静态变量加载完毕,然后加载静态块和静态方法的声明,只有当调用静态方法时才执行静态方法的内容。

7. 执行第六句static{ print("静态块"); } 所以调用print函数

    打印  8:静态块 i=7 n=99 由于n在上一步初始化了。

8. 执行main函数体StaticTest t = new StaticTest("init");同样分析思路和第3步是一样的,当声明了对象t时,程序会先执行非静态块和变量以及非静态方法的声明。然后执行类对象的初始化。所以先执行public int j = print("j");调用了print函数

    打印  9:j i=8 n=100

    然后执行非静态块print("构造块");调用了print函数

    打印  10:构造块 i=9 n=101

   最后执行对象的初始化,调用了构造函数public StaticTest(String str);

   打印  11:init i=10 n=102 

程序的入口函数依然是main函数,这里的知识点在于程序时类的加载过程和java虚拟机的内存分配。程序执行的顺序是,java虚拟机加载由.java编译生成出的.class字节码文件,将其加载至内存,然后找到了main函数,但并不是运行main函数的第一句,而是加载类的数据,当加载一个类时,JVM会根据属性的数据类型第一时间赋默认值(一举生成的),即数字类型初始化为0boolean初始化为false,引用类型初始化为null。然后再进行静态属性初始化,并为静态属性分配内存空间,静态方法的声明,静态块的加载,没有优先级之分,按出现顺序执行,静态部分仅仅加载一次。至此为止,必要的类都已经加载完毕,对象就可以被创建了。

当对象被创建时,就会调用类的动态属性,普通方法声明,构造块。最后在调用构造函数。

中的来说调用过程如下:

先加载类的静态属性(变量),静态块,静态方法的声明

然后当定义了类的对象时,调用非静态属性(变量),构造块,普通方法声明。

猜你喜欢

转载自www.cnblogs.com/cup-zh/p/9914622.html
今日推荐