[英]Please explain this behaviour in java
class abc extends TestStart{
static{
System.out.println("c");
}
{
System.out.println("f");
}
public abc(){
System.out.println("d");
}
}
public class TestStart {
static {
System.out.println("A");
}
{
System.out.println("z");
}
public TestStart(){
System.out.println("b");
}
public static void main(String[] args) {
TestStart x = new abc();
TestStart y = new TestStart();
}
}
输出-----------> czbfdzb
我认为此---- >>>>> TestStart的输出行为x = new abc(); - - - - 应该 :-
我应该得到以下输出:cfzbdzb
如果在父类和子类中没有init块,则此行为很大程度上是从此派生的。 请解释我提到的输出。
您得到了: A
c
z
b
f
d
z
b
而您却期望: A
c
f
z
b
d
z
b
因此,您说的是您希望f
在z
b
之前发生。
因此,您实际上要说的是您期望的:
f
)的实例初始化器 在之前被调用
z
)和 b
)的构造函数。 好吧,这根本不是事情发生的方式。 基类的所有实例初始化必须在派生类的实例初始化开始之前完成,否则派生类将能够访问基类的未初始化成员。
并且所有静态初始化内容( A
, c
)都是在问题中引发的红色鲱鱼,使我们感到困惑。
初始化后,所有类中的静态块和变量都会运行parent的初始化程序。 在父构造函数之后,然后是子构造函数中的子构造函数。 这是因为您可以在子初始化程序中使用某些父字段,因此必须在初始化之前对其进行初始化。
首先,命名:
public class TestStart {
static { // static initializer
System.out.println("A");
}
{ // instance initializer
System.out.println("z");
}
public TestStart() { // constructor
System.out.println("b");
}
}
没错,首先会调用静态初始值设定项,但您唯一的保证就是在任何上下文中使用该类之前都要先调用类静态初始值设定项。
对于实例初始化程序和构造函数,从第一次调用到最后一次调用的调用顺序如下:
Parent initializer, Parent Constructor, Your Initializer, Your Constructor
如果您使用this()
从同一个类中调用其他构造函数,则在类中所有构造函数调用之前,都会调用一次初始化器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.