11

私の教授の 1 人が、試験のためにいくつかの練習問題を提供してくれました。そのうちの 1 つは、次のようなものです (擬似コード)。

a.setColor(blue);
b.setColor(red);
a = b;
b.setColor(purple);
b = a;
//what color is a, and what color is b?

私には非常に初歩的なので、a は「赤」、b は「赤」という答えを提案しましたが、これは正しくないと言われました。数学の問題と同じように、答えを分解しました。

a = 15;
b = 12;
a = b; //a becomes 12
b = 13;
b = a; //b becomes 12

しかし、私の思考プロセスは、Java ではなく、C の頭脳によるものです。どちらにも普遍的な方法があると思いましたが、おそらく間違っていますか?私の答えは間違っていますか、それとも私の教授が間違っていますか? C、Python、および Web ロジック (PHP、Ruby) のコマンドをいくつか持っていますが、私は Java に非常に慣れていないため、これが些細なことである場合はお詫びします (それはそうです)。

4

6 に答える 6

18

すでに 2 つのオブジェクトを作成し、変数aを作成してそれらをb参照していると仮定すると、最初は次のようになります。

a -->  [ white ]     b --> [ white ]

最初の 2 行でオブジェクトの色が変わります。

a -->  [ blue  ]     b --> [  red  ]

a次に、によって参照されるオブジェクトに変数をポイントしbて、両方が同じオブジェクトを参照するようにします。あなたは今持っています

       [ blue  ]     b --> [  red  ] <-- a

次に、 によって参照されるオブジェクトの色を変更しますb

       [ blue  ]     b --> [ purple ] <-- a

最後に、 はすでに と同じオブジェクトを参照しているb=a;ため、この行は何もしません。ba

于 2013-10-21T21:23:13.317 に答える
6

これは、最初の例ではabがオブジェクトであるため、各ステップで次のようになるためです。

<-- はオブジェクトです

b <-- はオブジェクトです

a.setColor(青); ←a青くなる

b.setColor(赤); <--b赤くなる

a = b; <--重要::元のaオブジェクトは解放され、ガベージ コレクションに使用できるようになり、現在はobjectaの参照を保持していbます。これは、同じオブジェクトを参照していることを意味aします。bb

b.setColor(紫); <-- b は現在紫です。a は b のみを指しているため、a も紫

答え:この時点ではa、 との両方が紫色です。b

于 2013-10-21T21:18:10.547 に答える
4

認識すべき重要なことは、行の後には、a = bもう 2 つのオブジェクトがないということです。2 つの変数があり、どちらも同じオブジェクトを参照しています。したがって、そのオブジェクトの色を変更すると、両方の変数に反映されます。行b = aは実際には何もしません。

于 2013-10-21T21:16:29.790 に答える
3

Java では、オブジェクトである変数は、そのオブジェクト型の値へのポインターであると考えるのが一般的に正しいです。したがって、Java では次のようになります。

Color a = new Color(), b = new Color();

a.setColor(blue);
b.setColor(red);
a = b;
b.setColor(purple);
b = a;

C++ で以下とほぼ同じことを行う必要があります。

Color *a = new Color();
Color *b = new Color();

a->setColor(blue); // the value a points to is now blue
b->setColor(red); // the value b points to is now red
a = b; // a now points to the same value as b.
b->setColor(purple); // the value BOTH a and b point to is now purple
b = a; // this does nothing since a == b is already true

(これは参照と同じではないことに注意してください -この記事によると)。

また、プリミティブの場合、Java 変数は単なる値であり、ポインターではないことに注意してください。したがって、プリミティブ整数の場合、 の値を の値に等しくa = b設定しているため、質問で期待したとおりに多かれ少なかれ動作するはずです。ab

于 2013-10-21T21:17:30.953 に答える
2

aおよびオブジェクトへのb参照です。を記述a=bすると、以前に に割り当てられていた参照に が割り当てられるためb、両方とも同じオブジェクトを参照するようになります。

たとえば、O1 と O2 という 2 つのオブジェクトがあり、最初はそれぞれ と に割り当てられているaとしbます。

a.setColor(blue);     // the object O1 is set the color blue
b.setColor(red);      // the object O2 is set the color red
a = b;                // a now references O2, and b still references O2.
b.setColor(purple);   // the object O2 is set the color purple.
b = a;                // b is told to reference O2, which it already is.

C の精神を通して考えたい場合は、変数間で交換でき、データを変更できるポインタとしてaandを見ることができます。b

C のように処理されるプリミティブ値については、同じではありません。

于 2013-10-21T21:16:37.267 に答える
2

他の誰もが参照とプリミティブの違いを説明したので、これが表面下でどのように機能するかを説明します。

したがって、オブジェクトへの参照は本質的に数値です。VM に応じて、32 ビットまたは 64 ビットのいずれかになりますが、それでも数値です。この数字は、オブジェクトがメモリ内にあったことを示しています。これらの数値はアドレスと呼ばれ、通常は 16 進数で表記されます0xYYYYYYYY(これは 32 ビット アドレスの例で、64 ビット アドレスは 2 倍になります)。

32ビットVMを使用して上記の例を使用しましょう

a.setColor(blue); // Let's assume the object pointed to by a is at 0x00000001
b.setColor(red);  // Let's assume the object pointed to by b is at 0x00000010

/* Now the following makes sense, what happens is the value of 
   a (0x00000001) is overwritten with 0x00000010. 
   This is just like you would expect if a and b were ints.
*/
a = b; // Both a and b have the value 0x00000010. They point to the same object

b.setColor(purple); // This changed the object stored at 0x00000010 

b = a; // This says nothing because both a and b already contain the value 0x00000010

これは、2 番目の例で示したように、参照が数字のように機能することを示しているはずです。ただし、表面下でのみ、プログラマに関する限り、参照の割り当てはプリミティブの割り当てのようには機能しません。

Java では、オブジェクトのアドレスなどについて心配する必要はありません。低レベルのアクセスを可能にする C や C++ のような言語では、これはより明白で重要になります。

算数?では、算数やその他の数値でできることはできますか? 短い答えはノーです。少なくともJavaではそうではありません。

ただし、C および C++ では、オブジェクトへのポインターのインクリメントおよびデクリメントは完全に有効であり、たとえば配列のトラバースなどによく使用されます。

これが十分に明確でない場合は、遠慮なく質問してください。

于 2013-10-21T21:33:21.393 に答える