有关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()函数中生成继承了带有初始化器的父类的子类时,会调用子类中的父类构造方法,
在这个过程中也会执行初始化器。

广告
将在 10 秒后关闭
bannerAds