繁体   English   中英

Java:对象的初始化序列

[英]Java: initialization sequence of object

有一个代码作为初级Java开发人员的任务给出。 我在五年内使用Java,这段代码让我很困惑:

public class Main {

    String variable;

    public static void main(String[] args) {
        System.out.println("Hello World!");
        B b = new B();
    }

    public Main(){
        printVariable();
    }

    protected void printVariable(){
        variable = "variable is initialized in Main Class";
    }
}

public class B extends Main {

    String variable = null;

    public B(){
        System.out.println("variable value = " + variable);
    }

    protected void printVariable(){
        variable = "variable is initialized in B Class";
    }
}

输出将是:

Hello World!
variable value = null

但是如果我们改变String variable = null; String variable; 我们将有:

Hello World!
variable value = variable is initialized in B Class

第二个输出对我来说更清楚。 所以,据我所知,Java中的inizialisation序列如下:

  • 当我们来到这个根父类时,我们转到类层次结构的根(对于Java,它总是Object类):
    • 所有静态数据字段都已初始化;
    • 执行所有静态字段初始化程序和静态初始化程序段;
    • 初始化所有非静态数据字段;
    • 执行所有非静态字段初始化器和非静态初始化块;
    • 执行默认构造函数;
  • 然后我们重复底层子类的过程。

还有post描述了this关键字在超类的上下文中的行为 - 从基类方法调用基类重写函数

根据上面给出的规则,我假设有这样的序列:

  1. 我们将创建一个B类的新实例;
  2. 我们去零件类Main ;
  3. 用null初始化main.variable ;
  4. 然后我们转到Main类的默认构造函数;
  5. 构造函数在Main类中调用方法b.printVariable() ; (为什么不调用main.printvariable ?我们这里没有this关键词。)
  6. 字段b.variable变量在B类中初始化
  7. 现在我们回到B级;
  8. 我们应该用空值初始化字段b.variable ,我是对的吗?
  9. 执行了B类的默认构造函数

请,有人可以完整和完整地解释这种继承i​​nizialisation序列是如何工作的。 为什么更改String variable = null; String variable; 导致另一个输出。

顺序是:

  1. 主要 - >“你好”
  2. 主要 - >新B()
  3. B() - > Main() - > b.printVariable() - >设置变量
  4. 回到初始化B,所以变量= null。

所以基本上,超级对象Main()是在B类的任何初始化事件之前构造的。这意味着变量= null会在以后发生。 这是有道理的,否则B可以打破Main的初始化。

约书亚布洛赫在他有效的java书中介绍了很多关于如何做正确的危险继承的好理由,我会推荐它。

首先,您需要了解,当您编写variable = null;时会发生什么variable = null; 该代码何时执行。 这基本上决定了输出。

在开始之前,我还应该提到,当您创建class B对象时,不会调用主类的printVariable()函数。 相反,总是会调用B的printVariable()

记住这一点,当你有variable = null ,B的构造函数的执行将开始。 将调用First Main() ,它将调用printVariable()方法。 最后, variable=null ,将被称为覆盖variable变量。

在另一种情况下,如果你没有初始化variable=nullprintVariable()函数设置的variable将不会被覆盖,因此你得到的是你所期望的。

总之,当你执行new B()时,这是语句的执行顺序:

Main()     //super constructor
  B#printVariable()
  initializtion of variables in B's constructor (if any) [i.e. variable=null, if present]

这是一个很好的运动! 但要问初级开发人员,这不是一个公平的问题。 这个适合老年人。 但是为了使这个文本在技术访谈中有用,我通过在Main的构造函数中添加一个参数来修改它:

public Main(String something){
 printVariable();
}

如果该人将回答将要发生的事情,那么删除该论点并询问原始问题。 如果这个人不回答 - 没有必要继续 - 他/她是初中。

您还可以删除B类中受保护的限定符,并询问如果您的目标是不雇用此人将会发生什么:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM