一道研究 Java 初始化顺序的程序题,有种你就来。

函数式编程 · chengcheng222e · Created at · Last by chengcheng222e Replied at · 1420 hits
13

请大家仔细研究代码,直接写出控制台打印出来的顺序。

/**
 * Created with test
 * Description:
 * User: chenyuan
 * Date: 16/3/2
 * Time: 下午8:12
 */
public class Child extends Father {
    static {
        System.out.println("child-->static");
    }

    private int n = 20;

    {
        System.out.println("Child Non-Static");
        n = 30;
    }

    public int x = 200;

    public Child() {
        this("The other constructor");
        System.out.println("child constructor body: " + n);
    }

    public Child(String s) {
        System.out.println(s);
    }

    public void age() {
        System.out.println("age=" + n);
    }

    public void printX() {
        System.out.println("x=" + x);
    }

    public static void main(String[] args) {
        new Child().printX();
    }
}

class Father {

    static {
        System.out.println("super-->static");
    }

    public static int n = 10;
    public int x = 100;

    public Father() {
        System.out.println("super's x=" + x);
        age();
    }

    {
        System.out.println("Father Non-Static");
    }

    public void age() {
        System.out.println("nothing");
    }
}

写下大家的答案。


「软件匠艺社区」旨在传播匠艺精神,通过分享好的「工作方式」和「习惯」以帮助程序员更加快乐高效地编程。
共收到 7 条回复
1
hkliya · #1 ·

容我好好想想,三天后回来。

13

#1楼 @hkliya 哈哈 你忙 等你有时间了再来玩啊

1
hkliya · #3 ·

光聪老师来试试。

1
hkliya · #4 ·

我的答案,心里有点没底了

super-->static
child-->static
Father Non-Static
Child Non-Static
super’s x=100
nothing
The other constructor
child constructor body: 30
x=200
3
horance · #5 ·

@hkliya 我的答案和你一致。Java初始化的顺序:

  1. 类始化化(类加载时)
  2. 对象初始化
  3. 先父后子
  4. 从上而下
3
horance · #6 ·

@hkliya 跑了一下代码,有一个结果不得不说,结果如下:

super-->static
child-->static
Father Non-Static
super's x=100
age=0    // 特殊的输出结果                       
Child Non-Static
The other constructor
child constructor body: 30
x=200

解释

多态什么时候生效?

类初始化后,类与类的继承关系,方法列表等信息JVM已经获取了,多态调用机制(犹如C++的虚表)已经具备工作的条件了。为此,在Father的构造函数调用了可被覆写的函数age(不好的编码实践),按照预期,age的调用结果与多态机制一致。

零值初始化

但因为在初始化Father对象时,Child对象还未真正地初始化,Java默认地将Child对象的空间进行了零值初始化处理,为此,此刻Child对象的n0

结论:

不要企图在构造函数中调用可以被覆写的函数,以避免运行时的不确定性;一般地,构造函数一般只调用private(隐含了final的语义)的方法。

13

#6楼 @horance 是的,大部分的人都会认为age是30. 但是在打印这句话的时候,成员变量还没有开始初始化。所以就是0.

需要 Sign In 后回复方可回复, 如果你还没有账号你可以 Sign Up 一个帐号。