面对构造函数静态块和代码块的执行顺序问题
Facing Problem with order of execution of constructor static block and code block
我知道当我创建实例静态块时,首先初始化代码块,然后在此处构造我的代码
public class Main{
public Main() {
out.println("constructor initialised");
}
static {
out.println("static block initialised");
}
{
out.println("Code block initialised");
}
public static void main(String... args) {
new Main();
}
}
这样输出
静态块已初始化
代码块已初始化
构造函数初始化
上面的输出清楚了我的概念,但是当我像这样扩展一些 class 时
public class Main extends Bear{
public Main() {
out.println("constructor initialised");
}
static {
out.println("static block initialised");
}
{
out.println("Code block initialised");
}
public static void main(String... args) {
new Main();
}
}
熊Class
class Bear{
static {
out.println("static block initialised of bear class");
}
{
System.out.println("Code bLock initialised of bear class");
}
void run() {
out.println("running...");
}
}
输出如下:
bear 初始化的静态块class
静态块已初始化
bear 的代码块初始化 class
代码块已初始化
构造函数初始化
当扩展 class 时,执行顺序发生了变化 我不明白为什么会发生上面的输出
我相信这些工作的方式是:
- 静态块在 class 首次加载时调用(基本上是您第一次在项目中使用 class ),因此这些首先发生
- 初始化的(代码)块在开始时(在调用 super() 之后)基本上被复制到每个构造函数中,因此您可以共享代码(虽然不是很好的风格)
- 构造函数很好...构造函数...
它们按此顺序出现的原因是子 class 依赖于父 class 的存在。 child class 不能先于parent 加载,所以调用parent 的static initializer 加载它,然后再加载child class。
每个 class 加载后,它将调用构造函数(包括非静态代码块)来初始化您的对象。同样,子 class 依赖于存在并正确设置的父级,因此首先调用基础 class 构造函数,然后调用派生的 class 构造函数。需要按此顺序完成,以便子 class 可以依赖于父的某些参数。如果您将显式构造函数添加到基 class,您将获得如下所示的输出:
Class 已加载
- bear 初始化的静态块class
- 静态块已初始化
基础class构造函数
- 熊的代码块初始化class
- bear 的构造函数初始化 class
子class构造函数
- 代码块已初始化
- 构造函数初始化
如果您两次调用 new Main(),您会在第一次看到上面的输出,但第二次可能会丢失静态块,因为 class 已经加载。
我知道当我创建实例静态块时,首先初始化代码块,然后在此处构造我的代码
public class Main{
public Main() {
out.println("constructor initialised");
}
static {
out.println("static block initialised");
}
{
out.println("Code block initialised");
}
public static void main(String... args) {
new Main();
}
}
这样输出
静态块已初始化
代码块已初始化
构造函数初始化
上面的输出清楚了我的概念,但是当我像这样扩展一些 class 时
public class Main extends Bear{
public Main() {
out.println("constructor initialised");
}
static {
out.println("static block initialised");
}
{
out.println("Code block initialised");
}
public static void main(String... args) {
new Main();
}
}
熊Class
class Bear{
static {
out.println("static block initialised of bear class");
}
{
System.out.println("Code bLock initialised of bear class");
}
void run() {
out.println("running...");
}
}
输出如下:
bear 初始化的静态块class
静态块已初始化
bear 的代码块初始化 class
代码块已初始化
构造函数初始化
当扩展 class 时,执行顺序发生了变化 我不明白为什么会发生上面的输出
我相信这些工作的方式是:
- 静态块在 class 首次加载时调用(基本上是您第一次在项目中使用 class ),因此这些首先发生
- 初始化的(代码)块在开始时(在调用 super() 之后)基本上被复制到每个构造函数中,因此您可以共享代码(虽然不是很好的风格)
- 构造函数很好...构造函数...
它们按此顺序出现的原因是子 class 依赖于父 class 的存在。 child class 不能先于parent 加载,所以调用parent 的static initializer 加载它,然后再加载child class。
每个 class 加载后,它将调用构造函数(包括非静态代码块)来初始化您的对象。同样,子 class 依赖于存在并正确设置的父级,因此首先调用基础 class 构造函数,然后调用派生的 class 构造函数。需要按此顺序完成,以便子 class 可以依赖于父的某些参数。如果您将显式构造函数添加到基 class,您将获得如下所示的输出:
Class 已加载
- bear 初始化的静态块class
- 静态块已初始化
基础class构造函数
- 熊的代码块初始化class
- bear 的构造函数初始化 class
子class构造函数
- 代码块已初始化
- 构造函数初始化
如果您两次调用 new Main(),您会在第一次看到上面的输出,但第二次可能会丢失静态块,因为 class 已经加载。