クラスのロードと初期化:Java静的最終変数[重複]
Example.java
public class Example {
static final int i = 10;
static int j = 20;
static {
System.out.println("Example class loaded and initialized");
}
}
Use.java
import java.util.Scanner;
public class Use {
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
int ch = 1;
while(ch != 0) {
System.out.print("Enter choice: ");
ch = sc.nextInt();
if (ch == 1) {
System.out.println("Example's i = " + Example.i);
} else if(ch == 2){
System.out.println("Example's j = " + Example.j);
}
}
}
}
java -verbose:class Use
、を使用して実行し、入力を指定すると、1
出力は10
定数i
値になります。しかし、Example
クラスはまだロードされていません。私は、入力を与えたときしかし、2
、だけにして Example
クラスが冗長出力によって可視ように、JVMにロードされ、その後、実施例内の静的ブロックを実行し、またされるj
値が初期化され、その後、プリントの。
私のクエリは次のとおりです。入力の1
場合、つまりクラスの静的最終(定数)値がExample
別のクラスUse
で要求された場合、Example
それまでクラスがJVMにロードされなかった場合、その定数値はどこからフェッチされますか?静的ファイナルはいつ、どのようにi
初期化され、JVMメモリに格納されましたか?
回答
よるJava言語仕様のセクション12.4.1(強調追加):
クラスまたはインターフェイスタイプTは、次のいずれかが最初に発生する直前に初期化されます。
Tはクラスであり、Tのインスタンスが作成されます。
Tによって宣言された静的メソッドが呼び出されます。
Tによって宣言された静的フィールドが割り当てられます。
Tによって宣言された静的フィールドが使用され、フィールドは定数変数ではありません(§4.12.4)。
定数変数を使用して初期化され、最終的な変数である定数式。コードでExample.i
は、は定数変数であるため、クラスが読み込まれることはありません。
それで、クラスがロードされていない場合、値comはどこから来ますか?
言語仕様では、コンパイラーがその値をインライン化する必要があります。バイナリ互換性のセクションから13.1:
定数変数(§4.12.4)であるフィールドへの参照は、コンパイル時に定数変数の初期化子によって示される値Vに解決される必要があります。
そのようなフィールドが静的である場合、フィールドを宣言したクラスまたはインターフェイスを含め、フィールドへの参照がバイナリファイルのコードに存在してはなりません。このようなフィールドは常に初期化されているように見える必要があります(§12.4.2)。フィールドのデフォルトの初期値(Vと異なる場合)は絶対に守らないでください。