FinalキーワードがJVMクラスローダに与える影響


クラスにstatic finalとして宣言された変数がある場合、このような変数はクラスのローダに一定の影響を及ぼします.まず、次の例を見てみましょう.
package com.bird.classLoad;

class FinalTest{
	
	public static final int a = 6/3;
	
	static{
		System.out.println("FinalTest static block");
	}
}

public class Test3 {
	public static void main(String[] args) {
		System.out.println(FinalTest.a);
	}
}

aはstatic final変数であり、6/3に等しいため、コンパイル時にその値を知ることができるので、aに直接アクセスする値はFinalTestクラスの初期を引き起こすことはありません.
始化する.表現として、static静的コードはすぐにロードされません.
実行結果は
2

例を見て
package com.bird.classLoad;

import java.util.Random;

class FinalTest4{
	
	public static final int a = new Random().nextInt(100);
	
	static{
		System.out.println("FinalTest4 static block");
	}
}

public class Test4 {

	public static void main(String[] args) {
		System.out.println(FinalTest4.a);
	}
}

このstatic final変数aはiがコンパイル時に正確な値を知ることができないため、実行時になってからしか知ることができないので、自分でアクセスする
FinalTest4.aはFinalTest 4クラスの初期化を引き起こす.つまりstatic静的コードの速いロードです.
実行結果は
FinalTest4 static block
82

次の例では、子クラスがアクティブにアクセスされると、直接親クラスの初期化が起こります.
package com.bird.classLoad;

class Parent{
	
	static int a = 3;
	
	static{
		System.out.println("Parent static block");
	}
}

class Child extends Parent{
	
	static int b = 4;
	static{
		System.out.println("Chind static block");
	}
}

public class Test5 {
	
	public static void main(String[] args) {
		System.out.println(Child.b);
		
	}
}

Child,bに直接アクセスするため,まずParentクラスを初期化し,その後Childクラスを初期化する.
実行結果は
Parent static block
Chind static block
4

子クラスを介して親の変数に直接アクセスすると、子クラスは初期化されずに親のみが初期化されます.
package com.bird.classLoad;

class Parent{
	
	static int a = 3;
	
	static{
		System.out.println("Parent static block");
	}
}

class Child extends Parent{
	
	static{
		System.out.println("Chind static block");
	}
}

public class Test5 {
	
	public static void main(String[] args) {
		System.out.println(Child.a);
		
	}
}

Parentクラスのa変数に直接アクセスすると、parentクラスのみが直接初期化され、Childクラスは初期化されません
実行結果は次のとおりです.
Parent static block
3