web-dev-qa-db-ja.com

複数の同じオブジェクトのインスタンス化

同じオブジェクトを複数回インスタンス化すると、Javaで正確に何が起こりますか?

例えば:

_Test test = new Test();
_

その後、後で再びTest test = new Test();を呼び出すか、ループ内で呼び出します。以前のインスタンス化は破棄されますか?

8
userIsAMonkey
  1. new Test()を呼び出すたびに、Testクラスの新しいオブジェクトインスタンスが作成されます
  2. test = new Test();は、そのオブジェクトのreferenceを変数testに割り当てます
  3. 繰り返されるステートメントtest = new Test()は、Testの2番目のインスタンスを作成し、その参照を変数testに再度割り当てるため、最初の参照が置き換えられます。

ただし、最初のインスタンス化が破棄されるかどうかは、状況によって異なります。 Javaランタイム環境は参照をトレースするため、使用中のオブジェクトへの参照がある限り、オブジェクトは破棄されません。たとえば、ステップ2とステップ3の間で参照が最初のインスタンス化が別の場所(Test test2 = test;など)に格納されており、その変数がステップ3の発生時にまだスコープ内にある場合、test2はまだ参照を保持しているため、最初のオブジェクトは破棄されません。ただし、そのようなステートメントがなく、ステップ3で最初のオブジェクトへの唯一の参照が省略されている場合、そのオブジェクトの破棄が行われます。

破棄自体はすぐには行われませんが、後でガベージコレクターが実行されたときに行われることに注意してください。しかし、それは議論されたコードのセマンティクスから独立しています、それはメモリとパフォーマンスの問題だけです。

16
Doc Brown

1:言い回し:オブジェクトをインスタンス化するのではなく、クラスをインスタンス化します。クラスのインスタンス化の結果はオブジェクト(インスタンスとも呼ばれます)です。もちろん、インスタンス化のたびに新しい異なるオブジェクトを作成するために必要な回数だけクラスをインスタンス化できます。

2:何であれ、あなたが提案するコードを持てない:

Test test = new Test();
Test test = new Test();

どちらもこれを持つことはできません:

for (i=0; i<3; i++) {
    Test test = new Test();
    Test test = new Test();
}

部分Test testは変数test(タイプTest)の宣言であり、Javaを含む言語では同じ変数を2回宣言できないため、どれもコンパイルされません。同じスコープ。

ただし、次のように、異なる名前のオブジェクトを使用して(名前が示すように)同じ変数を複数回割り当てることができます。

Test test = new Test();
test = new Test();

1行目はtestを宣言し、新しく作成したオブジェクトを割り当てます。 2行目は、testに新しく作成された別のオブジェクトを割り当てます。

また、Javaではショートカットが許可されています。

for (i=0; i<3; i++) {
    Test test = new Test();
}

このループはtestを3回宣言しません。一度だけ宣言される変数testに3つの新しい異なるオブジェクトを順番に割り当てると理解されています。 (前のループと比較してください)。

3:変数testとタイプTestの2つのオブジェクトはどうなりますか?

変数testには、最初にオブジェクトの参照が割り当てられ、次に別のオブジェクトの参照が割り当てられます。変数は、最後に割り当てられた参照のみを保持します。

タイプTestの最初のオブジェクトはtestに割り当てられなくなりました。他の変数に参照が割り当てられていない場合、プログラムからこのオブジェクトにアクセスすることはできないため、役に立ちません。システムによるガベージコレクションの対象になります。ある時点で、システム(JVM)はガベージコレクターを実行し、メモリからそれをクリアします。

2番目のオブジェクトは、少なくとも1つの変数がそれを参照している限り存続し、ガベージコレクターもそれを処理して、参照されていないオブジェクトの墓地に移動します。 Javaオブジェクト:-(

5
mins