面试题看jvm类加载

2020-02-25  本文已影响0人  lv_shun

直接上代码

public class InitializeDemo {
    private static int k = 1;
    private static InitializeDemo t1 = new InitializeDemo("t1");
    private static InitializeDemo t2 = new InitializeDemo("t2");
    private static int i = print("I");
    private static int n = 99;
    static {
        print("静态块");
    }
    private int j = print("j");
    {
        print("构造块");
    }
    public InitializeDemo(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 InitializeDemo("init");
    }
}

这里需要理解jvm对类加载和对象加载两个流程

  1. 如果类中包含static字段或者静态代码块时,在类加载时会有<clinit>方法,对静态变量进行初始化,然后再执行init对象初始化。
  2. <clinit>执行过程中,静态变量和静态代码块执行优先级相同,执行顺序取决于书写顺序。
  3. <clinit>执行过程中,没有给静态变量赋值时,变量的其实是"零"值,这是在类加载的准备阶段赋予的值。
  4. 在对象初始化中,非静态成员变量和非静态代码块执行优先级相同,执行顺序取决于书写顺序,但是都优先于构造方法。

只说明了关键点,具体细节请看jvm类加载过程。
所以分析过程和输出结果为:
输出结果:

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

分析过程:

k=1
输出 1:j i=0 n=0
k=2
n=1
I=1
输出 2:构造块 i=1 n=1
k=3
n=2
I=2
输出 3:t1 i=2 n=2
k=4
I=3
n=3
输出 4:j i=3 n=3
k=5
I=4
n=4
输出 5:构造块 i=4 n=4
k=6
I=5
n=5
输出 6:t2 i=5 n=5
k=7
I=6
n=6
输出 7:i i=6 n=6
k=8
I=7
n=7

I=7
n=99

输出 8:静态块 i=7 n=99
k=9
I=8
n=100

输出 9:j i=8 n=100
k=10
I=9
n=101

输出 10:构造块 i=9 n=101
k=11
I=10
n=102

输出 11:init i=10 n=102
上一篇下一篇

猜你喜欢

热点阅读