私はクラスの3つの静的オブジェクト(同じクラス自体をインスタンス化)し、int型(Iと呼ばれる)変数がされたカラーと呼ばれています。私は、クラスを実行すると、「I」変数は、コンストラクタでインクリメントしているが、それはメモリ内に永続化されていない、コードの下にこれを説明してください
package test;
public class Color
{
public static Color RED = new Color();
public static final Color BLUE = new Color();
public static final Color GREEN = new Color();
static int i=0;
Color(){
System.out.println("Incrementing 'i' here "+(++i));
}
public static void main(String[] args) {
System.out.println("The 'i' variable is not incremented here, it still shows '0' , 'i' is: "+ Color.i ); // line 14
Color x = new Color();
System.out.println(x.i);
}
}
アウトは以下の通りです:
Incrementing 'i' here 1
Incrementing 'i' here 2
Incrementing 'i' here 3
The 'i' variable is not incremented here, it still shows '0' , 'i' is: 0
Incrementing 'i' here 1
1
クラスがロードされ、リンクされている場合、そのstatic
フィールドは、すべてデフォルト値に初期化されます。それが完了すると、静的フィールド初期化子は、このように、クラスの初期化を完了し、彼らはファイルに表示される順序で実行されています。このすべては、そのクラスが実行中で定義された任意のコードの前に起こります。それでは、ここで起こっては次のとおりです。
RED
、GREEN
、BLUE
、及びi
(そのデフォルト値に初期化されているnull
ためにColor
フィールドと0のためi
)。これは、任意の初期化子とは無関係であることに注意してください。- フィールドの初期化子は、
RED
(RED = new Color()
)を実行します。副作用として、i
1にインクリメントされます。 - フィールドの初期化子が
BLUE
実行され、i
2にインクリメントされます。 - フィールドの初期化子が
GREEN
実行され、i
3にインクリメントされます。 - 以下のための初期化
static
フィールドがi
実行され、i
値0が割り当てられます。 main()
この方法は、実行されと一致結果生成i
とき0でmain()
実行を開始します。
あなたには、このすべての血みどろの詳細を読むことができるJava言語仕様(JLS)の第12章およびJava仮想マシン仕様の第5章。
あなたはの宣言移動するだけで期待される出力を得ることができますi
先のことにColor
フィールドを:
static int i=0;
public static Color RED = new Color();
public static final Color BLUE = new Color();
public static final Color GREEN = new Color();
その後、出力は次のようになります。
「I」ここで1インクリメント
「I」ここで2インクリメント
ここでインクリメント「I」3
「I」変数はここでインクリメントされない、それは「0」、「i」は示していまだ:3
ここでインクリメント「iが」4
4
注意final
修飾子がいるので、ここで初期化の順序には影響しませんGREEN
し、BLUE
「定数変数」ではありませんJLSにおけるその用語の定義によれば。定数変数(単語の不運なペアリング)がプリミティブまたはあるString
両方に宣言された変数final
および定数式に初期化。この場合には、new Color()
定数式ではなく、Color
一定の変数の適切なタイプではありません。例えば、参照してください§4.12.4JLSの。