java动手动脑

发布时间 2023-09-30 00:08:50作者: 席

一、运行TestStaticInitializeBlock.java示例

有三个类:`Root`、`Mid` 和 `Leaf`,它们都包含了静态初始化块(`static`),实例初始化块(非静态初始化块,使用代码块 `{}` 表示),以及构造方法。在 `TestStaticInitializeBlock` 类中创建了 `Leaf` 类的实例。观察输出结果,可以总结出以下关于静态初始化块和实例初始化块执行顺序的规则:

1. 静态初始化块是类加载时执行的,只会执行一次,不管有多少个类的实例。
2. 实例初始化块在每次创建类的实例时都会执行,且在构造方法之前执行。

基于上述规则,下面是代码的执行顺序和输出结果:

```
Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的实例初始化块
Root的无参数构造方法
Mid的实例初始化块
Mid的无参数构造方法
Mid的带参数构造方法
Mid的无参数构造方法
Leaf的构造方法
```

 

1. 首先,`Leaf` 类的静态初始化块会在类加载时执行,因此先输出 "Leaf的静态初始化块"。
2. 接下来,创建 `Leaf` 类的实例,首先执行了 `Leaf` 类的实例初始化块,输出 "Leaf的实例初始化块"。
3. 然后,执行了 `Leaf` 类的构造方法,构造方法中通过 `super("Javaʾ");` 调用了 `Mid` 类的带参数构造方法。
4. 在 `Mid` 类的带参数构造方法中,首先会调用 `this();`,这里调用了 `Mid` 类的无参数构造方法。
5. `Mid` 类的无参数构造方法中会执行实例初始化块,输出 "Mid的实例初始化块",然后执行无参数构造方法,输出 "Mid的无参数构造方法"。
6.回到 `Mid` 类的带参数构造方法,输出 "Mid的带参数构造方法"。
7. 最后,回到 `Leaf` 类的构造方法,输出 "ִLeaf的构造方法"。

静态初始化块会在类加载时执行,而实例初始化块会在每次创建实例时执行,构造方法会在实例初始化块之后执行。这个顺序保证了在创建对象时,先初始化父类的成员,再初始化子类的成员。

二、以下代码为何无法通过编译?哪儿出错了?

尝试创建一个 `Foo` 类的实例时,没有提供一个无参数的构造方法,但是在 `main` 方法中尝试使用无参数的构造方法来创建实例。

在 Java 中,如果显式定义了一个构造方法,编译器将不会自动生成默认的无参数构造方法。在Foo` 类中,定义了一个带参数的构造方法 `public Foo(int initValue)`,没有提供无参数构造方法。因此,当尝试使用无参数构造方法创建 `Foo` 类的实例时,编译器会报错,因为无法找到匹配的构造方法。

要解决这个问题,可以提供一个无参数的构造方法,或者在 `main` 方法中使用带参数的构造方法来创建 `Foo` 类的实例,例如:

```java
public class Test {
public static void main(String[] args) {
Foo obj1 = new Foo(42); // 使用带参数的构造方法创建实例
}
}

class Foo {
int value;

public Foo(int initValue) {
value = initValue;
}

public Foo() {
// 无参数构造方法
// 可以不做任何操作,或者设置一个默认值
}
}
```