我找到这个例子,我想了解它背后的逻辑?构造函数和静态块以及初始化程序块如何在继承中工作?在哪一个阶段被称为?
public class Parent {
static {
System.out.println("i am Parent 3");
}
{
System.out.println("i am parent 2");
}
public Parent() {
System.out.println("i am parent 1");
}
}
public class Son extends Parent {
static {System.out.println("i am son 3");}
{System.out.println("i am son 2");}
public Son() {
System.out.println("i am son 1");
}
public static void main(String[] args) {
new Son();
}
}
输出是:
i am Parent 3
i am son 3
i am parent 2
i am parent 1
i am son 2
i am son 1
答案 0 :(得分:11)
你需要知道
super(params)
的构造函数,或者是否要使用默认构造函数super()
。如果是默认构造函数,则不必显式编写它。super(...)
调用因此,类被编译成类似于此的类。
public class Parent {
static {
System.out.println("Parent static block");
}
public Parent() {
super();
{
System.out.println("Parent initializer block");
}
System.out.println("Parent constructor");
}
}
public class Son extends Parent {
static {
System.out.println("Son static block");
}
public Son() {
super();
{
System.out.println("Son initializer block");
}
System.out.println("Son constructor");
}
public static void main(String[] args) {
new Son();
}
}
为了能够从main
类执行Son
方法,JVM需要加载此类的代码(以及它扩展的类)。在类完全加载后,JVM 初始化其静态内容,涉及执行静态块(是的,一个类中可能有多个静态块)。要完全加载Son
类,JVM需要知道其父类的详细信息,以便它在Parent
之前完全加载Son
类,这意味着它还将在{{{}}中的静态块之前执行其静态块。 1}}类。
因此输出如下:
Son
Parent static block
现在在Son static block
方法中,您通过main
调用Son
类构造函数,代码类似于
new Son()
由于super();
{
System.out.println("Son initializer block");
}
System.out.println("Son constructor");
引用了super()
类构造函数,它是
Parent
结果你会看到
super();// this will invoke Object constructor since Parent
// doesn't extend anything (which means it extends Object class)
{
System.out.println("Parent initializer block");
}
System.out.println("Parent constructor");
Parent initializer block
这会处理Parent constructor
执行的Parent#constructor()
,接下来您会看到super()
生成后的Son构造函数的代码
super()
Son initializer block
要在使用Son constructor
构造函数甚至Son
方法之前看到要加载的类,您可以在使用main
构造函数之前打印一些内容,例如
Son
将导致
System.out.println("ABC // before new Son()");
new Son();
答案 1 :(得分:9)
当JVM加载并初始化类时,会调用一次静态块。在构造类的实例时执行实例初始化程序,就像构造函数一样。
中描述了静态和实例初始值设定项答案 2 :(得分:2)
当你的类加载时调用静态块,你的类首先由jvm中的类加载器加载,所以首先它们被执行
然后你创建对象所以你的父init块被调用然后你的父构造函数由于java中的构造函数链接然后派生类init块然后派生类构造函数
答案 3 :(得分:1)
当类加载到JVM中时执行静态块,而在创建实例时执行构造函数块。
静态初始值设定项相当于静态上下文中的构造函数。你肯定会比实例初始化器看到更多。