Java-这段代码中的初始化顺序是什么?
在下面的Java代码中,昆虫类由甲壳虫类继承Java-这段代码中的初始化顺序是什么?,java,oop,Java,Oop,在下面的Java代码中,昆虫类由甲壳虫类继承 class Insect { private int i = 9; protected int j; Insect() { System.out.println("i = " + i + ", j = " + j); j = 39; } private static int x1 = printInit("static Insect.x1 initia
class Insect {
private int i = 9;
protected int j;
Insect() {
System.out.println("i = " + i + ", j = " + j);
j = 39;
}
private static int x1
= printInit("static Insect.x1 initialized");
static int printInit(String s) {
System.out.println(s);
return 47;
}
}
public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized");
public Beetle() {
System.out.println("k = " + k);
System.out.println("j = " + j);
}
private static int x2
= printInit("static Beetle.x2 initialized");
public static void main(String[] args) {
System.out.println("Beetle constructor");
Beetle b = new Beetle();
}
}
输出在某种程度上是一致的
已初始化static.x1
静态甲壳虫.x2已初始化
甲虫构造器
i=9,j=0
甲虫
k=47 j=39
此特定示例中的初始化顺序是什么?
为什么x2在x1之后立即初始化?为什么主方法(System.out.println(“甲壳虫构造函数”);
)的第一行在x1和x2初始化之后执行。太令人困惑了
我知道派生类构造函数会自动调用基类构造函数(除非它有参数并且您会使用super关键字)。我知道变量在构造函数之前初始化,静态变量在其他变量之前初始化。
x1
和x2
是静态的。这意味着它们在类加载时被初始化。由于main方法位于bellet
中,因此必须在调用main
之前加载该类。这就是为什么您首先看到的是x1
和x2
初始化。我不知道为什么这两个人的顺序是这样的
现在您正在调用main
和System.out.println(“甲虫构造函数”)代码>被执行。然后它调用甲虫()
,甲虫()首先隐式调用超级()
(又称昆虫()
)。这将打印i=9,j=0
,因为i
是9,并且j
在该点尚未初始化,这意味着它具有默认的int值0
现在j
被设置为39,并且在甲壳虫()
中继续流动。现在,在您的例子中,k
初始化了甲壳虫
的字段。因此,对于甲壳虫()
中的显式代码,k
由超级构造函数初始化为47,j
初始化为39。x1
和x2
是静态的。这意味着它们在类加载时被初始化。由于main方法位于bellet
中,因此必须在调用main
之前加载该类。这就是为什么您首先看到的是x1
和x2
初始化。我不知道为什么这两个人的顺序是这样的
现在您正在调用main
和System.out.println(“甲虫构造函数”)代码>被执行。然后它调用甲虫()
,甲虫()首先隐式调用超级()
(又称昆虫()
)。这将打印i=9,j=0
,因为i
是9,并且j
在该点尚未初始化,这意味着它具有默认的int值0
现在j
被设置为39,并且在甲壳虫()
中继续流动。现在,在您的例子中,k
初始化了甲壳虫
的字段。因此,对于bellet()
中的显式代码,k
由超级构造函数初始化为47,j
初始化为39-
由于静态成员是非实例成员,即在类的所有实例中只共享成员的一个副本,因此首先初始化这些成员
在这种情况下,x1首先被初始化,因为它是存在main方法的类的基类中的静态成员
因此,1st x1被初始化
子类中的静态成员x2之所以出现,是因为同样的原因,也因为昆虫类中没有其他静态成员
甲虫构造器行是从主方法打印出来的
超类和子类的构造函数一个接一个地被调用,原因很明显这可以解释如下-
由于静态成员是非实例成员,即在类的所有实例中只共享成员的一个副本,因此首先初始化这些成员
在这种情况下,x1首先被初始化,因为它是存在main方法的类的基类中的静态成员
因此,1st x1被初始化
子类中的静态成员x2之所以出现,是因为同样的原因,也因为昆虫类中没有其他静态成员
甲虫构造器行是从主方法打印出来的
超级类和子类的构造函数被一个接一个地调用,原因很明显JVM(类加载器)在调用甲虫类的主要静态方法时加载甲虫类。类加载后,将初始化甲壳虫类,这意味着初始化该类的所有静态成员
基类总是隐式初始化的,因此可以看到x1在x2之前初始化
您会看到在x1和x2之后打印的“甲壳虫构造函数”,因为当您引用一个类的静态方法(正如您调用main所做的那样)时,JVM的执行顺序会跳到初始化类的静态成员,然后再继续执行main()方法
作为一个实验,尝试将主方法移到另一个类中
public class Beetle1 {
public static void main(String[] args) {
System.out.println("Beetle1 constructor");
}
}
现在由于甲虫构造函数没有被引用,类加载器不会加载它,您将看到打印的甲虫1构造函数。JVM(类加载器)在调用甲虫类的主要静态方法时加载甲虫类。类加载后,将初始化甲壳虫类,这意味着初始化该类的所有静态成员
基类总是隐式初始化的,因此可以看到x1在x2之前初始化
您会看到在x1和x2之后打印的“甲壳虫构造函数”,因为当您引用一个类的静态方法(正如您通过调用main所做的那样)时,JVM的执行顺序会跳到初始化cla