需要关于Java构造的信息吗

需要关于Java构造的信息吗,java,constructor,Java,Constructor,我最近注意到java中的这种构造允许在调用构造函数之前执行代码: public class Foo { { System.out.println("before constructor 1"); } public Foo () { System.out.println("constructor"); } { System.out.println("before constructor 2");

我最近注意到java中的这种构造允许在调用构造函数之前执行代码:

public class Foo {

    {
        System.out.println("before constructor 1");
    }

    public Foo () {
        System.out.println("constructor");
    }


    {
        System.out.println("before constructor 2");
    }

}
对于此类,调用构造函数时:

new Foo();
这将到达输出:

before constructor 1
before constructor 2
constructor
我想知道更多关于这个构造的信息:它是如何被称为文档页面url的,当它被添加时…

这是一个

编译器按照给定的顺序连接类中的所有实例初始化器块,然后将结果复制到所有构造函数的开头,包括隐式no args one(如果适用)

这些代码的语义与您自己将这些代码复制到构造函数中的唯一不同之处是,您有一个超类构造函数调用。实例初始化器允许您在调用
super()
之前运行代码,但语言规则不允许您使用此属性编写构造函数

类似的机制用于处理字段初始化器。定义如下字段时:

int something = 3;
它将生成
something=3
,并将其复制到每个构造函数的开头(在任何实例初始化器之前)


同样有趣的是

答案中有一个错误的可能重复-如果您有一个与super匹配的构造函数,那么父构造函数调用必须是构造函数的第一行。在构造函数之前执行代码的唯一方法是使用这个实例初始化器块。实例初始化器块只是由编译器复制到每个构造函数的开头。在您编写的每个构造函数的开头调用super是一个与此机制无关的语言规则。我将明确提到这一点,因为这是唯一一种语义实际上不同于到处复制粘贴代码的情况。这些注释的意思是这些块不是在构造函数之前执行的-它们是在构造函数的开头执行的,在执行构造函数中的其余语句之前,类似于初始化实例变量的方式。当使用调试器进入构造函数时,即使没有这些块,也很容易看到这一点。是的。这正是我的回答。编译器会将这些块复制到所有构造函数中。没有什么神奇的“构造函数之前”的地方可以让代码运行,只有这个方便的简写法可以让代码在所有构造函数中结束。同样的机制也用于变量初始值设定器:但我上面已经说过了。