JavaRush /Java Blog /Random-JA /コンストラクターと通常のメソッドの違い。
fog
レベル 18

コンストラクターと通常のメソッドの違い。

Random-JA グループに公開済み
コンストラクターは、オブジェクトのフィールドの値を最初に設定することを目的とした特別なメソッドです。 一見したところ、オブジェクト コンストラクターは通常のオブジェクト メソッドとあまり変わりません。実際、コンストラクター内では、通常のオブジェクト メソッドで実行できることはすべて実行できます。コンソールへのテキストの出力、新しいオブジェクトのすべてのフィールドとメソッドへのアクセス、例外のスローなどです。通常のメソッドと同様に、コンストラクターには引数を指定できます。オーバーロードされたメソッドと同様に、異なるシグネチャを持つ複数のコンストラクターが存在する可能性があります。ジェネリック メソッドと同様に、コンストラクターは型変数によってパラメーター化できます。<init>コンパイラーによって生成されたバイトコードを調べても、コンストラクターへの呼び出しがあるべき場所で、他のメソッドへの呼び出しと何ら変わらない名前のメソッドへの呼び出しが見つかります。オブジェクト。このメソッドのバイトコードを見つけると、コンストラクターのコンパイル結果が含まれていることがわかります。従来の方法と大きな違いはないようですが、かなり重要な違いが存在します。まず、実際になぜコンストラクターが必要なのかを考えてみましょう。プリミティブ型、配列、オブジェクトなどのデータを保存および処理するには、一定量のメモリが必要です。これは、プロセッサ レジスタ、スタック スペース、プロセス データ セクションまたはメモリの動的に割り当てられた部分 (ヒープ) に割り当てられたスペースの一部です。多くのプログラミング言語では、高速化の目的で、プログラムが新しいメモリを要求すると、そのメモリはクリアされずにプログラムに与えられ、以前にこのメモリ セルに格納されていた任意のデータが含まれる可能性があります。最終的に意味のあるデータ構造がそこに存在するように、必要な値を準備してメモリに書き込むことは、完全にプログラマーの肩にかかっています。ごく自然なことですが、プログラマーは作業を楽にしたいと考え、頻繁に使用されるデータ構造を初期化する (つまり、初期値を設定する) ルーチンを作成しました。このようなルーチンはほぼ常に使用されていたため、Java 言語の作成者は、オブジェクトの作成時にこのような初期化ルーチンを呼び出すことを必須にすることを決定し、それらをコンストラクターと呼びました。Java で新しいオブジェクトが作成されると、次のことが起こります。 まず、Java メモリ マネージャーが、オブジェクトを収容するために必要なメモリ量を割り当てます。この場合、作成されたオブジェクトのクラスで直接宣言されたフィールドだけでなく、このクラスのすべての祖先で宣言されたフィールドも考慮されます。さらに、このボリュームには、Java マシンが内部ニーズに使用する構造を配置するためのスペースが含まれています。nullこのような「空白」のすべてのフィールドは、参照型、0数値、およびfalseなどのデフォルト値に自動的に設定されます。boolean。この後、クラス コンストラクターが自動的に呼び出され、そのタスクはオブジェクトのフィールドの初期値を設定することです。通常のメソッドでは最初のステートメントは何でも構いませんが、コンストラクターの自由度ははるかに低くなります。コンストラクターの最初のステートメントは、同じクラスの別のコンストラクターへの明示的な呼び出しであるか、親クラスのコンストラクターへの明示的または暗黙的な呼び出しである必要があります。this同じクラスのコンストラクターへの明示的な呼び出しは、キーワードの後に​​かっこで囲まれた一連の引数を使用して行われます。親クラスのコンストラクターを明示的に呼び出すことはまったく同じ方法で行われますが、キーワードが使用されますsuper。同じクラスまたは親クラスのコンストラクターへの明示的な呼び出しの引数では、オブジェクトのフィールドやメソッドにアクセスしたり、キーワード や を使用したりすることはできません。これは、コンストラクターへの明示的な呼び出しによって静的コンテキストが導入されるためthisですsuper。親クラスのコンストラクターを暗黙的に呼び出すには、何も記述する必要はありませんが、デフォルトのコンストラクターが暗黙的に呼び出されます。このコンストラクターは存在し、現在のクラスから認識できる必要があります。同時に、チェーンのObject先頭にあるクラス コンストラクターが作業を正常に完了する前に、呼び出し元の親コンストラクターのチェーンが中断されると、オブジェクト、つまりメソッドがファイナライズできなくなることに留意する必要があります。finalize()そのようなオブジェクトの関数は決して呼び出されません。親クラスのコンストラクターが完了すると、制御は現在のクラスのインスタンス初期化子ブロックとインスタンス フィールド初期化子に暗黙的に転送されます。イニシャライザは、プログラム テキストに出現する順序で実行されます。イニシャライザの作業が完了した後でのみ、制御が残りのコンストラクタに転送されます。コンストラクターの残りの機能は、Java メモリー モデルに関連します。クラス、またはその祖先の 1 つがメソッドをオーバーライドする場合finalize()、コンストラクターの完了はメソッドが実行される前 ( happens-beforefinalize() ) に行われます。コンストラクターの完了後にスレッドがオブジェクトへの参照を参照した場合、このスレッドは、finalコンストラクターの完了前に初期化が行われたオブジェクトの正しく初期化された -fields を参照することが保証されます。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION