【问题标题】:Are statements under curly braces load first?花括号下的语句是否首先加载?
【发布时间】:2026-01-22 01:45:01
【问题描述】:

我知道静态内容首先加载到内存中,但为什么我没有提到它是静态的,但为什么在“CT”之前打印“IT”?

class Person
{
    Person()
    {
        System.out.print(" CP");
    }

    static 
    {
        System.out.print("SP");
    }
}

class Teacher extends Person
{
    Teacher()
    {
        System.out.print(" CT");
    }

    {
        System.out.print(" IT");
    }
}


public class StaticTest 
{
    public static void main(String[] args) 
    {       
        Person p = new Teacher();
    }
}

【问题讨论】:

    标签: java inheritance static block


    【解决方案1】:

    {System.out.print(" IT");} 等初始化程序块在构造函数之前执行。实际上,它们被复制到每个构造函数的开头。

    初始化实例成员

    通常,您会将初始化实例变量的代码放在 构造函数。使用构造函数有两种选择 初始化实例变量:初始化块和最终方法。

    实例变量的初始化块看起来就像静态的 初始化块,但没有 static 关键字

    {
    // 初始化所需的任何代码都放在这里
    }

    Java 编译器将初始化程序块复制到每个构造函数中。 因此,这种方法可以用来在之间共享一个代码块 多个构造函数。

    (Source)

    更准确地说,这是JLS 中描述的初始化顺序:

    1. 将构造函数的参数分配给此构造函数调用新创建的参数变量。

    2. 1234563如果该构造函数调用突然完成,则此过程出于相同原因而突然完成;否则,继续第 5 步。
    3. 此构造函数不以显式构造函数调用同一类中的另一个构造函数开始(使用 this)。如果此构造函数用于 Object 以外的类,则此构造函数将以显式或隐式调用超类构造函数开始(使用 super)。使用这五个相同的步骤递归地评估超类构造函数调用的参数和过程。如果该构造函数调用突然完成,则此过程出于相同的原因突然完成。否则,继续第 4 步。

    4. 执行该类的实例初始化程序和实例变量初始化程序,将实例变量初始化程序的值分配给相应的实例变量,按照它们在源代码中的文本出现的从左到右的顺序班级。如果执行这些初始化程序中的任何一个导致异常,则不会处理更多初始化程序,并且此过程会突然完成相同的异常。否则,继续第 5 步。

    5. 执行此构造函数的其余部分。如果该执行突然完成,则此过程出于同样的原因突然完成。否则,此过程正常完成。

    请注意,实例初始化程序在第 4 步中执行,在构造函数主体之前(第 5 步)。

    【讨论】:

    • 非常感谢,内容丰富..真的很感激 :)