[英]Java: initialization sequence of object
There is a code which is given as a task for a junior Java developers. 有一个代码作为初级Java开发人员的任务给出。 I use Java during five years and this piece of code completely confusing me:
我在五年内使用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";
}
}
The output will be: 输出将是:
Hello World!
variable value = null
But if we change String variable = null;
但是如果我们改变
String variable = null;
to String variable;
到
String variable;
we will have: 我们将有:
Hello World!
variable value = variable is initialized in B Class
The second output is more clear for me. 第二个输出对我来说更清楚。 So, as far as I know the sequence of inizialisation in Java like this:
所以,据我所知,Java中的inizialisation序列如下:
Also there is post which describes the behavior of the this
keyword in context of a superclass - Calling base class overridden function from base class method 还有post描述了
this
关键字在超类的上下文中的行为 - 从基类方法调用基类重写函数
Based on the rules given above, I assume to have sequence like this: 根据上面给出的规则,我假设有这样的序列:
B
; B
类的新实例; Main
; Main
; main.variable
with null; main.variable
; Main
; Main
类的默认构造函数; b.printVariable()
in class Main
; Main
类中调用方法b.printVariable()
; (Why doesn't it call main.printvariable
? We don't have this
key word here.) main.printvariable
?我们这里没有this
关键词。) b.variable
" variable is initialized in B Class " b.variable
“ 变量在B类中初始化 ” B
; B
级; b.variable
with null value, am I right?; b.variable
,我是对的吗? B
executed B
类的默认构造函数 Please, can someone give a complete and full explanation of how this inheritance inizialisation sequence works. 请,有人可以完整和完整地解释这种继承inizialisation序列是如何工作的。 And why changing
String variable = null;
为什么更改
String variable = null;
to String variable;
到
String variable;
leads to another output. 导致另一个输出。
The sequence is: 顺序是:
So basically, the super object Main() is constructed before any intialisation events of class B. Which means variable=null occurs later. 所以基本上,超级对象Main()是在B类的任何初始化事件之前构造的。这意味着变量= null会在以后发生。 This makes sense as otherwise B could break the initialisation of Main.
这是有道理的,否则B可以打破Main的初始化。
Joshua Bloch covers a lot of good ground in his effective java book about how dangerous inheritance is to get right, I would recommend it. 约书亚布洛赫在他有效的java书中介绍了很多关于如何做正确的危险继承的好理由,我会推荐它。
First, you need to understand, what happens when you write variable = null;
首先,您需要了解,当您编写
variable = null;
时会发生什么variable = null;
. 。 When is that code executed.
该代码何时执行。 This basically determines the output.
这基本上决定了输出。
Before I begin, I should also mention that when you create an object of class B
, the printVariable()
function of the main class is not called. 在开始之前,我还应该提到,当您创建
class B
对象时,不会调用主类的printVariable()
函数。 Instead, always the printVariable()
of B will be called. 相反,总是会调用B的
printVariable()
。
Keeping this in mind, when you have variable = null
, the execution for B's constructor will begin. 记住这一点,当你有
variable = null
,B的构造函数的执行将开始。 First Main()
will be called, which will call the printVariable() method. 将调用First
Main()
,它将调用printVariable()方法。 At last, variable=null
, will be called overwriting the variable
variable. 最后,
variable=null
,将被称为覆盖variable
变量。
In the other case, where you do not initialize variable=null
, the variable
set by the printVariable()
function will not be overwritten, hence you get what you were expecting. 在另一种情况下,如果你没有初始化
variable=null
, printVariable()
函数设置的variable
将不会被覆盖,因此你得到的是你所期望的。
In summary, this is the order of execution of statements, when you do new B()
: 总之,当你执行
new B()
时,这是语句的执行顺序:
Main() //super constructor
B#printVariable()
initializtion of variables in B's constructor (if any) [i.e. variable=null, if present]
This is a nice exercise! 这是一个很好的运动! But it's not a fair question to ask junior developers.
但要问初级开发人员,这不是一个公平的问题。 This one is for seniors.
这个适合老年人。 But to make this text useful during the technical interview, I'd modified it by adding an argument to the Main's constructor:
但是为了使这个文本在技术访谈中有用,我通过在Main的构造函数中添加一个参数来修改它:
public Main(String something){
printVariable();
}
If the person will answer what will happen, then remove the argument and ask the original questions. 如果该人将回答将要发生的事情,那么删除该论点并询问原始问题。 If the person won't answer - there is no need to continue - s/he is junior.
如果这个人不回答 - 没有必要继续 - 他/她是初中。
You can also remove the protected qualifier in class B and ask what will happen if you have a goal not to hire this person :) 您还可以删除B类中受保护的限定符,并询问如果您的目标是不雇用此人将会发生什么:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.