序文
Javaでは、オブジェクトを使用する前に正しく初期化する必要があります。これは、Java仕様によって規定されています。
自動初期化(デフォルト)
クラスのすべての基本データメンバーが初期化されます。次の例を実行して、これらのデフォルト値を表示します。
class default {boolean t; Char C;バイトB;ショートS; int i;長いl;フロートF;ダブルD; public void show(){system.out.println( "基本タイプ初期化値/n" + "boolean <----->" + t + "/n" + "char <------>" + c + "/n" + "byte <-------->" + b + "/n" + "short <------>" + "/n" + " +" + l + "/n" + "float <------>" + f + "/n" + "double <----->" + d + "/n"); }} public class initvalue {public static void main(string [] args){default d = new default(); D.Show(); }}【操作結果】:
基本タイプの初期化値
boolean <------> false
char <------>
バイト<------> 0
短い<------> 0
int <------> 0
long <------> 0
フロート<------> 0.0
ダブル<------> 0.0
ここで、 charタイプのデフォルト値はnullです。
非プライティブデータ型の場合、オブジェクトのハンドルも初期化されます。
クラスパーソン{プライベート文字列名; // setter} class default {person P; public void show(){system.out.println( "person <----->" + p); }} public class initvalue {public static void main(string [] args){default d = new default(); D.Show(); }}【操作結果】:
人<-----> null
ハンドルの初期化値がnullであることがわかります。これは、Pの初期化値を指定せずにp.setNameに類似したメソッドが呼び出される場合、例外が発生することを意味します。
規制初期化
最初の値を変数に自分で割り当てる必要がある場合は、変数を定義しながら値を割り当てることができます。
class default {boolean t = true; char c = 'a';バイトb = 47;短いs = 0xff; int i = 24; long l = 999;フロートF = 1.2F;ダブルD = 1.732; public void show(){system.out.println( "boolean <----->" + t + "/n" + "char <------>" + " +" + "/n" + "byte <------>" + b + "/n" + "short <------>" + s + "/n" + "int <------->"/n " +" + " +" + " + "float <------>" + f + "/n" + "double <------>" + d + "/n"); }} public class initvalue {public static void main(string [] args){default d = new default(); D.Show(); }}1つの方法で初期化することもできます。
class person {int i = set(); // ...}これらの方法は、独立変数を使用することもできます。
クラスパーソン{int i; int j = set(i); // ...}ビルダーの初期化
ビルダーの初期化の利点は、ランタイム中に初期化値を決定できることです。例えば:
クラスパーソン{int age; person(){age = 89; }}年齢は最初に0に初期化され、次に89になります。これは、すべての基本タイプとオブジェクトへのハンドルに当てはまります。
初期化順序
クラスでは、初期化の順序は、クラス内で変数が定義される順序によって決定されます。可変定義がメソッド定義の中央に大きく広がっている場合でも、変数はメソッド(コンストラクターを含む)を呼び出す前にまだ初期化されます。例えば:
class pet {pet(int age){system.out.println( "pet(" + age + ")"); }} class person {Pet T1 = new Pet(1); person(){system.out.println( "--- person()---"); T3 =新しいペット(33); }ペットt2 = new Pet(2); void show(){system.out.println( "show ----- running"); } PET T3 = new PET(3);} public class orderofInitialization {public static void main(string [] args){person p = new person(); p.show(); }}【操作結果】:
ペット(1)
ペット(2)
ペット(3)
- 人() - -
ペット(33)<br/>
show ----ランニング
上記の例では、T1、T2、およびT3の定義はクラス全体にありますが、初期化の順序は、T1、T2、およびT3の定義順序によって決定されます(結果を確認するためにT1、T2、およびT3を自分で変更します)。人のビルダーが呼ばれると、T3は再目的化されます。
静的データの初期化
データが静的な場合、同じプロセスが実行されます。プリミティブタイプであり、初期化されていない場合、独自の標準プリミティブタイプの初期値を自動的に取得します。オブジェクトのハンドルの場合、オブジェクトが作成されて接続されていない限り、オブジェクトの値が得られます。定義時に初期化された場合、静的には1つのストレージ領域しかないため、撮影された方法は非静的な値とは異なります。例えば:
class Bowl {bowl(int marker){system.out.println( "bowl(" +マーカー + ")"); } void f(int marker){system.out.println( "f(" +マーカー + ")"); }} class table {static bowl b1 = new Bowl(1); table(){system.out.println( "table()"); b2.f(1); } void f2(int marker){system.out.println( "f2(" +マーカー + ")"); } static bowl b2 = new Bowl(2);}クラスの食器棚{Bowl b3 = new Bowl(3);静的ボウルB4 =新しいボウル(4); cupboard(){system.out.println( "upboard()"); b4.f(2); } void f3(int marker){system.out.println( "f3(" +マーカー + ")"); } static bowl b5 = new bowl(5);} public class staticInitialization {public static void main(string [] args){system.out.println( "メインの新しい食器棚()の作成");新しい食器棚(); System.out.println( "メインで新しい食器棚()の作成");新しい食器棚(); T2.F2(1); T3.F3(1); } static table t2 = new Table();静的食器棚t3 = new upboard();}【操作結果】:
ボウル(1)
ボウル(2)
テーブル()
f(1)
ボウル(4)
ボウル(5)
ボウル(3)
食器棚()
F(2)
主に新しい食器棚()を作成します
ボウル(3)
食器棚()
F(2)
主に新しい食器棚()を作成します
ボウル(3)
食器棚()
F(2)
F2(1)
F3(1)
静的コードブロック
Javaを使用すると、他の静的初期化作業をクラスの特別なコードブロックに分割することができます。このコードブロックは、静的キーワードの形式で、その後に静的コードブロックと呼ばれるメソッド本体が続きます。静的コードブロックは、そのクラスのオブジェクトが初めて生成された場合、またはそのクラスに属する静的メンバーが初めてアクセスされる場合にのみ実行されます。例えば:
class person {person(int age){system.out.println( "person(" + age + ")"); } void f(int age){system.out.println( "f(" + age + ")"); }} class persons {静的人P1;静的人P2; static {p1 = new person(1); P2 =新しい人(2); } persons(){system.out.println( "persons()"); }} public class explicittatic {public static void main(string [] args){system.out.println( "Inside main()"); persons.p1.f(18); // 1}静的人x = new persons(); // 2 static persons y = new Person(); // 2}静的オブジェクトP1に1回マークされた行でアクセスする場合、または1行目がコメントされ、2行目がコメントされていない場合、人の静的初期化モジュールが実行されます。 1と2の両方がコメントアウトされている場合、人に使用される静的コードブロックは実行されません。
静的プロパティと静的コードブロックの実行の順序
class person {person(int age){system.out.println( "person("+age+")"); }} class persons {static person p = new person(2); // 1 static {p = new person(3); }静的人p =新しい人(2); // 2} public class compstaticInit {public static void main(string [] args){} static persons x = new Persons;}Annotation 1を保持するアノテーション1および注釈2を保持する結果の分析によれば、静的特性と静的コードブロックの実行順序はエンコードの順序によって異なることがわかります。先にいる人は誰でも最初に実行されます。
非静的特性の初期化
class animal {animal(int age){system.out.println( "animal(" + age + ")"); } void f(int age){system.out.println( "f(" + age + ")"); }} public class notStaticInit {Animal A1;動物A2; {a1 = new Animal(1); a2 = new Animal(2); System.out.println( "a1&a2初期化"); } notstaticInit(){system.out.println( "notstaticInit"); } public static void main(string [] args){system.out.println( "Inside main()"); notstaticInit x = new notStaticInit(); }}静的コードブロックと同様に、非静的特性を持つ匿名コードブロックの初期化順序は、エンコーディング順序に依存します。
継承されたオブジェクトの初期化プロセス
クラス昆虫{int i = 1; int j; INSECT(){prt( "i =" + i + "、j =" + j); j = 2; } static int x1 = prt( "static insect.x1初期化"); static int prt(string s){system.out.println(s); 3を返します。 }}パブリッククラスのカブトムシは昆虫を拡張します{int k = prt( "beeklt.k initialized"); beetle(){prt( "k =" + k); prt( "j =" + j); } static int x2 = prt( "static botle.x2初期化"); static int prt(string s){system.out.println(s);返品4; } public static void main(string [] args){prt( "Beetle constructor");ビートルB = new Beetle(); }}【操作結果】:
静的INESECT.X1初期化
static Bootle.x2初期化
カブトムシコンストラクター
i = 1、j = 0
Beeklt.k初期化
k = 4
J = 2
ビートルでJavaを実行しているときに最初に起こることは、そのクラスを屋外で見つけるためのローダーです。ローディングプロセス中、ローダーは基本クラスを発見するため、それに応じてロードされます。このプロセスは、基礎となるクラスのオブジェクトが生成されるかどうかに関係なく実行されます。基本クラスに別のベースクラスが含まれている場合、他のベースクラスにロードされます。次に、ルートベースクラスで静的初期化を実行し、次のデリバティブクラスで実行するなどを実行します。これは、デリバティブクラスの初期化が、基礎となるクラスメンバーの初期化に依存する可能性があるためです。
すべてのクラスがロードされると、オブジェクトを作成できます。まず、このオブジェクトのすべての基本データ型はデフォルト値に設定され、オブジェクトハンドルはnullに設定されます。次に、基本クラスのビルダーを実行します。この状況は自動的に行われます( super(),ベースクラスのビルダーもスーパーを通して指定できます)。ベースクラスのビルダーが完了すると、派生クラスインスタンス変数が元の順序で初期化され、ビルダーの残りのボディ部分が実行されます。
オブジェクト作成のプロセスを要約してください。
静的実行は、クラスがロードされ、1回だけの場合にのみ実行されます。
非静的は、インスタンス化された場合にのみ実行され、オブジェクトが作成されるたびに実行されます。
静的実行は非静的で前に実行され、ベースクラスの静的は派生クラスよりも静的実行に先行します。
静的プロパティと静的コードブロックの実行プロパティは、クラス内の位置に依存し、誰が最初に実行します。
非静的な特性とコンストラクターブロックの実行順序は、クラスの位置とそれらの前で実行する人に依存します。
要約します
上記の紹介を通じて、Javaのオブジェクトを初期化するいくつかの方法と、初期化コードの実行方法を理解し、非Initializatial変数を使用する可能性のある状況も導入します。これらの問題を詳細に理解した後、オブジェクトが表示される前に完全に初期化されるように、エンコードのリスクを回避できます。