java中的内联初始化块

sab*_*abu 4 java initialization

我上课了

public class MyMain{
    public static void main(String... arg){
            Temp t = new Temp(){
                {
                    System.out.println(" instance initialize");
                }
            };

        }
    }

class Temp{
    int i;

    {
        i=9;
        System.out.println("Static"+i);
    }
    Temp(){
        System.out.println("Temp const "+i);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我执行main方法时输出到:

Static9
Temp const 9
instance initialize
Run Code Online (Sandbox Code Playgroud)

理想情况下,块在构造函数之前执行,但是在构造函数之后调用内联初始化块.为什么?

Jon*_*eet 16

你要创建一个子类Temp.对于每个类,任何实例初始值设定项都在构造函数体之前执行 - 但是超类在子类初始化之前经历初始化.所以执行流程是:

  • 初始化器 Object
  • 构造函数体 Object
  • 初始化器 Temp
  • 构造函数体 Temp
  • 匿名类中的初始化程序
  • 匿名类中的构造函数体(无)

我强烈建议你重构任何看起来像这样的代码 - 旨在澄清而不是聪明.


NPE*_*NPE 6

JLS 12.5阐明了施工过程中发生的事情的顺序(强调我的):

在作为结果返回对新创建的对象的引用之前,处理指示的构造函数以使用以下过程初始化新对象:

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

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

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

总而言之,超类构造函数(步骤3)在实例初始化器之前执行(步骤4).两者都在"此构造函数的其余部分"(在您的示例中没有)之前执行.