有关Java初始化程序的顺序
初始化函数是什么意思?
这是用于在类加载时或实例化时初始化字段的东西。
加载时使用static初始化器(以下称为static{}),实例化时使用初始化器(以下称为{})。
在JavaGold之前的范围内,只有这两个,但是它们的顺序和调用方式有些复杂,
所以我做了一个总结备忘。
基本的代码与解释
class Foo{
//イニシャライザ
{System.out.print("A");}
//コンストラクタ
Foo() {System.out.print("B");}
}
class Test{
//staticイニシャライザ
static {System.out.print("C");}
//main()
public static void main(String[] args){
//インスタンス化
Foo foo = new Foo();
}
}
因为觉得难以看清楚,我只换了一下类和main()的行。如果反而更难看清楚的话,我很抱歉。
CAB
解释
static{}在类加载时被加载,因此在包含main()方法的Test类中,”C”会首先被输出。接下来,在main()方法中创建了Foo类对象。
在此过程中,{}会先于构造函数被调用,然后才调用构造函数。
因此输出顺序是”CAB”。
有些复杂的代码和解释
class Foo{
{System.out.print("A");}
Foo() {System.out.print("B");}
}
class Bar{
//フィールド
static int i = 1;
//イニシャライザ
{System.out.print("D");}
//staticイニシャライザ
static {System.out.print("C");}
//コンストラクタ
Bar() {System.out.print("E");}
}
class Test{
//main()
public static void main(String[] args){
//Fooクラスのインスタンス化
Foo foo = new Foo();
//Barクラスの変数iを出力
System.out.print(Bar.i);
//Barクラスのインスタンス化
Bar bar = new Bar();
}
}
这就是执行结果。
ABC1DE
解释
最初的main()的第一行与前述的基本代码相同,将输出”AB”。
第二行的Bar变量i输出的是,由于变量i是静态的,因此不需要生成。当尝试进行处理时,在输出之前会执行static{}。因此可以看出,输出的顺序是”C1″。
随后,会生成Bar类,并进行{}和constructor的处理,输出”DE”。此时static{}已经输出过一次,因此无论是否尝试重新生成,处理都不会执行。
另外还有
删除Bar类变量i的输出语句并执行,结果是ABCDE。代码的顺序是static{}之后,但执行顺序是{}之后。
最后
我在这段代码中最先怀疑的是,如果static{}在main()所在的类以外,它会不会被首先加载?最终发现类只有在被调用时才会被加载,这个意识真是太好了。
补充
我忘了写关于初始化程序的事情,现在补上来。
・在Interface中使用初始化器的写法会导致编译错误。(可能)
→如果有人能写出正确的写法,麻烦将其评论分享一下,非常感谢。
・关于初始化器。当在main()函数中生成继承了带有初始化器的父类的子类时,会调用子类中的父类构造方法,
在这个过程中也会执行初始化器。