花括号下的语句首先加载吗?

时间:2014-11-29 08:09:46

标签: java inheritance static block

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

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();
    }
}

1 个答案:

答案 0 :(得分:6)

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

  

初始化实例成员

     

通常,您可以使用代码初始化a中的实例变量   构造函数。使用构造函数有两种选择   初始化实例变量:初始化程序块和最终方法。

     

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

     

{
      //无论初始化需要什么代码都在这里   }

     

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

Source

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

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

  2.   
  3. 如果此构造函数以同一个类中的另一个构造函数的显式构造函数调用(第8.8.7.1节)开头(使用此方法),则使用这五个相同步骤计算参数并以递归方式处理该构造函数调用。如果该构造函数调用突然完成,则此过程突然完成,原因相同;否则,继续步骤5.

  4.   
  5. 此构造函数不以同一类中另一个构造函数的显式构造函数调用开头(使用此方法)。如果此构造函数用于Object以外的类,则此构造函数将以超类构造函数的显式或隐式调用开始(使用super)。使用这五个相同的步骤评估参数并递归处理超类构造函数调用。如果该构造函数调用突然完成,则此过程突然完成,原因相同。否则,请继续执行步骤4.

  6.   
  7. 为此类执行实例初始值设定项和实例变量初始值设定项,将实例变量初始值设定项的值按从左到右的顺序分配给相应的实例变量,在这些顺序中它们以文本方式出现在源代码中类。如果执行任何这些初始值设定项导致异常,则不会处理其他初始化程序,并且此过程会突然完成同样的异常。否则,请继续步骤5.

  8.   
  9. 执行此构造函数的其余部分。如果执行突然完成,则此过程突然完成,原因相同。否则,此过程正常完成。

  10.   

请注意,实例初始值设定项在构造函数体之前的步骤4中执行(步骤5)。