3

Java で java オブジェクトの引数を method に渡すとき、myMethod((MyObject) myObject)基本的には C++ で のように object への参照を渡すようなものmyFunction(& myObject)です。そのような場合、Java 開発者は C++ プログラマーとほぼ同じ自由度を持っています。参照を渡したい場合はオブジェクトを渡すだけで、コピーしたい場合はメソッドで手動で行います。

しかし、ここに私の質問があります:

特定のタイプのオブジェクトを持つ3つの異なる配列があるとしましょうMyObject

MyObject[] myObjectsOne

MyObject[] myObjectsTwo

MyObject[] myObjectsThree

私はそれらを別々に持つ必要がありますが、上記の 3 つの要約のような代替配列も 1 つ必要です。たとえば、3 つすべてのコンテンツを表示するために単一のオブジェクトとして使用されます。

シナリオ: 値を実際にどこにもコピーせずに、最初の 3 つの値を表す 4 番目の配列を作成します。(これらの値に余分なメモリを割り当てません)

C++ では、これら 3 つのテーブル内の対応するオブジェクトへの参照を含むテーブルを作成するだけです。

Java では、私たちのために作られているだけだといつも思っていましたが、考え始めたときはよくわかりませんでした。

また、次のようになりました。MyObject[] myObjectsFour

そして出演後..

myObjectsFour[0] = myObjectsOne[0];

..メモリレベルで同じオブジェクトに実際にアクセスすることを意味します かmyObjectsFour[0]? 私が理解しているように、そうでなければ、そうでなければなりませんmyObjectsOne[0]myObjectsFour[0] = myObjectsOne[0].clone();

4

2 に答える 2

5

背景テキストから少し誤解があると思います。

Java では、メソッド myMethod((MyObject) myObject) に java オブジェクト引数を渡すとき、基本的には C++ で myFunction(& myObject) のようにオブジェクトへの参照を渡すようなものです。

Java は「参照渡し」言語ではありません。常に値渡しです。オブジェクトを渡すときは、そのオブジェクトへの参照をで渡します。これは、C++ でポインタを値で渡す場合と似ています。

たとえば、Java では次のようになります。

public void myMethod(MyObject myObject) {
    myObject = null;
}

「MyObject」として渡されるオブジェクトは、値による参照のみです。したがって、null に設定しても、渡された元のオブジェクトには影響しません。対応して:

public void myMethod(MyObject myObject) {
    myObject.myIntProperty = 15;
}

上記のように、オブジェクトのメンバーにアクセスすると、実際のオブジェクトへのアクセスが行われます。これは、オブジェクトがまだそのオブジェクトへの参照であるためです。それが役立つ場合は、渡されmyObjectた元のオブジェクトのメモリ位置と同じメモリ位置のコピーがあると考えてください。

public void myMethod(MyObject myObject) {}
/* Example memory address: 0x009FC12A in memory, 
   a *copy* of the same address of the object that was passed */

この考え方で、あなたの質問を見てみましょう。これは何をもたらしますか:

myObjectsFour[0] = myObjectsOne[0];

Java は値によって要素の参照を割り当てるので、myObjectsFour[0]今では正確に同じオブジェクトを指しています。これの意味は:

myObjectsFour[0] = myObjectsOne[0];    
myObjectsFour[0].myIntProperty = 15;

またmyObjectsOne[0].myIntProperty、上記と同様に、 の値を 15 に変更します。ただし、これを行う:

myObjectsFour[0] = myObjectsOne[0];
myObjectsFour[0] = null; // (or anything else, for that matter)

には影響しませんmyObjectsOne[0]。ステートメントによって同じ変数ではありませんmyObjectsFour[0] = myObjectsOne[0];。同じ参照のコピーを持つ単純な 2 つの変数です。

それは理にかなっていますか?

于 2013-04-11T16:03:37.830 に答える
1

はい、同じオブジェクトにアクセスします。

コメントの一部の人々が指摘したように、Java 参照は C++ 参照よりも C++ ポインターに似ていますが、それらを削除する必要がなく、ポインター演算を実行できないという違いがあります。

オブジェクトが Java 配列または Java コレクションに挿入されると、データ構造はコピーではなく元のオブジェクトを指します。

  • 配列またはコレクションのコピーを作成しても、その中のオブジェクトはコピーされません。新しいデータ構造は同じオブジェクトを指します。
  • 配列またはコレクション内のオブジェクトで何かを変更すると、オブジェクトが追加された他のすべてのコレクションでも変更されます。これらはすべて同じオブジェクトを指しているためです。
  • 配列またはコレクションからオブジェクトを削除しても、オブジェクトは削除されません。それへの他のポインターは有効なままです。(それへの他のポインターが存在しなくなると、ガベージコレクターによって最終的に削除されます)。
  • コレクションまたは配列が削除されても、それが指しているオブジェクトは影響を受けません (ガベージ コレクターがそれらへのポインターが他に存在しないことに気付かない限り)。
于 2013-04-11T15:52:34.620 に答える