明らかに、このようなコードが実際に発生することはありません。恐ろしいです。なぜ 7 になるのかを心配するのにあまり時間をかけるべきではないと思いますが、実際にはその理由を理解するのはそれほど難しくありません。
評価される最初のフィールド値はInterfaceA.A
であるため、VM は初期化を開始しますInterfaceA
。それには が必要なInterfaceB.B
ので、初期化を開始しますInterfaceB
。それには が必要なInterfaceC.C
ので、初期化を開始しますInterfaceC
。
InterfaceC.C
を参照していますInterfaceA.A
が、VM は既に初期化されているため、関係なく処理を続行します ( JLS のセクション 12.4.2InterfaceA
に従って)。
C の Class オブジェクトが、現在のスレッドによって C の初期化が進行中であることを示している場合、これは初期化の再帰的な要求である必要があります。LC を解放し、正常に完了します。
はまだ0 であり (どのような値が必要InterfaceA.A
かはまだ調査中です。0 は のデフォルト値です)、値は 1 (0 + 1) になります。次に、値 2 (1 + 1) を取得し、値 4 (2 * 2) を取得します。int
InterfaceC.C
InterfaceB.B
InterfaceA.A
これらのフィールド値をすべて合計すると、最終的に 7 になります。
別の式を使用すると、別のインターフェイスが最後に初期化されるため、別の値が得られますが、参照する最初のフィールドにのみ依存します。
A + B + C = 7 (A = 4, B = 2, C = 1)
A + C + B = 7 (A = 4, B = 2, C = 1)
B + A + C = 3 (A = 0, B = 2, C = 1)
B + C + A = 3 (A = 0, B = 2, C = 1)
C + A + B = 6 (A = 2, B = 1, C = 3)
C + B + A = 6 (A = 2, B = 1, C = 3)
(もちろん、これは型の初期化に関するものであるため、既存のコード行を置き換える必要があります。行を追加するだけSystem.out.println
で、上記のすべての式に対して同じ答えが得られます。)