Java实例初始化块和实例变量

4

根据我之前的问题Java classes and static blocks,如果我将代码从静态块和变量改为普通的实例化块和实例变量,那么代码会如何执行?

class extra3 {
    public static void main(String string[]) {
        Hello123 h = new Hello123();
        System.out.println(h.a);
    }
}
class Hello123 {
    {
        a=20;
    }
    int a=158;
}

这里我的输出是158,我不理解其中的原因。另一段代码如下:

class extra3 {
    public static void main(String string[]) {
        Hello123 h = new Hello123();
        System.out.println(h.a);
    }
}
class Hello123 {
    int a=158;
    {
        a=20;
    }
}

这里的输出是20,这是可以接受的,因为在创建对象时实例块首先被执行。但为什么第一个代码的输出为158?


从我所看到的,代码是串行执行的,这也应该是正确的。 - Subhrajyoti Majumder
3个回答

5

这是初始化的顺序

  1. 将字段设置为默认初始值(0、false、null)
  2. 调用对象的构造函数(但不执行构造函数体)
  3. 调用超类的构造函数
  4. 使用初始化器和初始化块初始化字段
  5. 执行构造函数体

因此,在初始化字段时,内联初始化器(a = 158)和初始化块(a = 20)按照定义的顺序执行。

所以在第一种情况下,内联初始化器在初始化块之后执行,你会得到 158 的结果。

在第二种情况下,初始化块在内联初始化器之后执行。


1
非常感谢。解释得很好。 - Shashank Agarwal
我还有一个疑问。当实例块中设置'a'时,为什么'a'能够编译通过,因为'a'明显没有被声明? - Shashank Agarwal
@ShashankAgarwal:我不理解你的问题。 - Abimaran Kugathasan
@ShashankAgarwal - 'a' 被正确编译,因为当构造函数被调用时,在步骤1中实例变量就已经被设置为默认值。请查看“已接受的答案”排序。在示例1中,'a' 被设置为0,然后为20,最后为158。 - javadg

1

顺序很重要。

初始化和静态块会根据它们在源代码中的顺序执行。这就是原因。


1

静态块按照在代码中声明的顺序执行。这篇文章将帮助您理解静态和非静态初始化块的执行顺序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接