静的変数初期化順序
1。簡単なルール
まず、最も一般的なJavaコードを見てみましょう。
パブリッククラステスト{public static test1 t = new test1(); public static int a = 0; public static int b; public static void main(string [] arg){system.out.println(test.a); System.out.println(test.B); }} class test1 {public test1(){test.a ++; test.b ++; }}コンソールの出力結果は何ですか?
わかりました、たぶんあなたは以下の結果を推測したので、あなたはまだJavaに精通しています。
次のようにコードをコピーします:0 1
上記の結果が出力である理由がわからない場合は、お知らせします。
Java静的変数初期化は、次のルールに従います。
これを読んだ後、テストの価値が3回変更されたことを理解できます。
宣言されたときに0に設定>> test1 :: test1が1 >> test.aが0に設定されています。
2。複雑なルール
これを理解している場合は、以下のコードをご覧ください。
パブリッククラスA {public static int b = ba; public static a plus = new a( "a"); public static final int finalInt =(int)(math.random()*100); public static b p = new b( "a"); public static final string finalstr = "finalstr"; public static final Integer finalInteger = new Integer(10); public static int a = 1; public static b c = null; public a(string from){system.out.println( "----------- begin a :: a --------------"); system.out.println( "a :: a、from ="+from); system.out.println( "a :: a、ab ="+ab); system.out.println( "a :: a、a.finalint ="+a.finalint); System.out.println( "a :: a、ba ="+ba); System.out.println( "a :: a、b.plus ="+b.plus); system.out.println( "----------- end a :: a ---------------"); } public static void main(string [] arg){system.out.println( "main、ab ="+ab); System.out.println( "main、bt ="+bt); system.out.println( "main、ca ="+ca); }} class B {public static int t = aa; public static a plus = new a( "b"); public static int a = 1; public b(string from){system.out.println( "----------- Begin b :: b -------------------"); system.out.println( "b :: b、from ="+from); System.out.println( "b :: b、ba ="+ba); System.out.println( "b :: b、aa ="+aa); System.out.println( "b :: b、ap ="+ap); System.out.println( "b :: b、a.plus ="+a.plus); System.out.println( "b :: b、a.finalint ="+a.finalint); System.out.println( "b :: b、a.finalint ="+a.finalint); System.out.println( "b :: b、a.finalint ="+a.finalint); System.out.println( "b :: b、a.finalint ="+a.finalint); System.out.println( "B :: B、A.FinalInteger ="+A.FinalInteger); System.out.Println( "B :: B、A.FINALSTR ="+A.FINALSTR); system.out.println( "----------- end b :: b ---------------"); }} class c {public static final a a = new a( "c");}まだ出力の結果を推測できますか?テスト中に書いたので、推測しませんでした。ハハ
コンソール出力の結果は次のとおりです。
----------- Begin A :: A ---------------- A :: A、From = Ba :: A、AB = 0A :: A、A.FinalInt = 0a :: A、Ba = 0a :: A、B.Plus = null -----------エンドA :: a.finalint = 0a :: a、ba = 1a :: a、b.plus=a@a90653------------------------- a :: a ------------------------ B :: b --------------- B :: b、from = ab :: b、ba = 1b :: b、aa = 0b :: b、ap = nullb :: b、a。 a.finalint = 61b :: b、a.finalinteger = nullb :: b、a.finalstr = finalstr = finalstr ---------- end b :: b -----------------メイン、ab = 1main、bt = 0 ---------- A :: b.plus=a@a90653----------エンドa :: A -------------------メイン、CA = A@61DE33
あなたはこの結果を推測しませんでした、ハハ。
プログラムの実行結果を1つずつ説明するのに多くの時間がかかります。ここでは、ルールを直接書き留めた後、Java static変数の初期化が続きます。
最初の段落のルールはまだ有効ですが、それらは健全ではありません。
静的データの初期化
静的な適格フィールドを追加することは、いわゆるクラスフィールドです。つまり、このフィールドの所有者はオブジェクトではなくクラスです。作成されたオブジェクトの数に関係なく、静的データのコピーは1つだけです。
静的フィールドは常にクラスで初期化され、一般フィールドが初期化されます。次に、コンストラクターを初期化します。ただし、このクラスのオブジェクトが作成されていない場合、オブジェクトは初期化されず、1回だけ実行されます。
次のコードと同様に、静的イニタイシャル化クラスでは、静的テーブルテーブル= new Table();最初に、次にテーブルオブジェクトが初期化されません。それ以外の場合は、初期化されません。
クラスボウル{Bowl(int marker){print( "bowl(" + marker + ")"); } void f1(intマーカー){print( "f1(" +マーカー + ")"); }} class table {static bowl1 = new Bowl(1); table(){print( "table()"); bowl2.f1(1); } void f2(intマーカー){print( "f2(" +マーカー + ")"); } static bowl bowl2 = new Bowl(2);}クラスの食器棚{Bowl Bowl3 = new Bowl(3);静的ボウルボウル4 =新しいボウル(4); upboard(){print( "upboard()"); bowl4.f1(2); } void f3(intマーカー){print( "f3(" +マーカー + ")"); } static bowl5 = new bowl(5);} public class staticInitialization {public static void main(string [] args){print( "main");新しい食器棚(); print( "メイン州で新しい食器棚()の作成");新しい食器棚(); Table.F2(1); upboard.f3(1); }静的テーブルテーブル= new Table();静的食器棚食器棚=新しい食器棚();}出力:
ボウル(1)ボウル(2)テーブル()f1(1)ボウル(5)ボウル(3)ボウル(3)食器棚()f1(2)メインボウル(3)udipboard()f1(2)メインボウル(3)の食器棚()F1()F1(2)F2(1)F3(1)で新しい食器棚()を作成します。
表示された静的初期化(つまり、静的ブロック)
静的ブレースに複数の初期化ステートメントを置くことは、静的ブロックと呼ばれます。実際、それは複数の統計を書くことによって一緒に書かれており、エッセンスは同じです。オブジェクトが初めて作成された場合、またはクラスのフィールドに初めてアクセスされる場合にのみ実行されます。
クラスカップ{cup(int marker){print( "cup(" + marker + ")"); } void f(intマーカー){print( "f(" +マーカー + ")"); }} class cups {static cup1;静的カップカップ2; static {cup1 = new Cup(1); cup2 = new Cup(2); } cups(){print( "cups()"); }} public class explicittatic {public static void main(string [] args){print( "Inside main()"); cups.cup1.f(99); //(1)} // static cups cups1 = new Cups(); //(2)// static cups cups2 = new Cups(); //(2)}出力:
内部main()カップ(1)カップ(2)f(99)
非静的なインスタンス初期化
これについて言うことは何もありません。それは、順番に実行された通常の初期化だけでなく、複数回実行できます。
クラスマグ{マグ(intマーカー){print( "マグ(" +マーカー + ")"); } void f(intマーカー){print( "f(" +マーカー + ")"); }} public class Mugs {Mug Mug1;マグMUG2; {mug1 = new Mug(1); MUG2 =新しいマグ(2); print( "mug1&mug2初期化"); } mugs(){print( "mugs()"); }マグ(int i){print( "mugs(int)"); } public static void main(string [] args){print( "Inside main()");新しいマグ(); print( "new Mugs()完了");新しいマグ(1); print( "新しいマグ(1)完成"); }}内部Main()Mug(1)Mug(2)Mug1&Mug2 initialMugs()new mugs()rectremedMug(1)MUG(2)MUG1&MUG2 InitialMugs(int)新しいマグ(1)完成