0

以下のコードでは、両方のオブジェクトがまったく同じオブジェクトへの参照を持っていると仮定しましたが、以下の例では間違っていると言っています。重複していたらすみません。

    class A {
        public String a;
        public void set(String a) {
            this.a = a;
        }
    }

    class B {
        public String b;
        public void set(String b) {
            this.b = b;
        }
    }

    A aC = new A();
    B bC = new B();

    String str = "aaa";

    aC.set(str);
    bC.set(aC.a);

    aC.a += "a";

    System.out.println(aC.a);
    System.out.println(bC.b);
4

5 に答える 5

3

Java Spec は、Java のすべてが値渡しであると述べています。Javaには「参照渡し」というものはありません。

これを理解するための鍵は、次のようなものです

Dog myDog;

犬ではありません。実際には、Dog へのポインタです。

それが意味するのは、あなたが持っているときです

Dog myDog = new Dog("Rover");
foo(myDog);

基本的に、作成された Dog オブジェクトのアドレスを foo メソッドに渡しています。

(基本的に b/c Java ポインターは直接アドレスではないと言いますが、そのように考えるのが最も簡単です)

Dog オブジェクトがメモリ アドレス 42 にあるとします。これは、メソッドに 42 を渡すことを意味します。

メソッドが次のように定義されている場合

public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}

何が起こっているのか見てみましょう。

  • パラメータ someDog は値 42 に設定されています
  • 行「AAA」で
    • someDog は、それが指す Dog (アドレス 42 の Dog オブジェクト) に続きます。
    • その犬 (アドレス 42 の犬) は、名前をマックスに変更するように求められます。
  • 行「BBB」で
    • 新しい犬が作成されます。彼が住所74にいるとしましょう
    • パラメータsomeDogを74に割り当てます
  • 行「CCC」
    • someDog は、それが指す Dog (アドレス 74 の Dog オブジェクト) に続きます。
    • その犬 (アドレス 74 の犬) は、名前を Rowlf に変更するように求められます。
  • その後、戻ります

次に、メソッドの外側で何が起こるかを考えてみましょう。

myDog は変更されましたか?

鍵があります。

myDog はポインターであり、実際の Dog ではないことに注意してください。答えは NO です。myDog の値は 42 のままです。まだ元の Dog を指しています。

アドレスをたどって、その末尾にあるものを変更することは完全に有効です。ただし、変数は変更されません。

Java は C とまったく同じように機能します。ポインターを割り当て、ポインターをメソッドに渡し、メソッド内でポインターをたどり、ポイントされたデータを変更できます。ただし、そのポインターが指す場所を変更することはできません。

于 2013-03-09T18:06:55.697 に答える
3

Javaは値渡しです。参照は値によって渡されます。

aC.a += "a"新しい String オブジェクトを作成するため、bC に反映されません。

文字通り、あなたは言っています

aC.a = aC.a + "a"

したがって、その=記号を解釈して、 と を連結した新しい String オブジェクトにマップすることを意味しaC.aます。ただし、 の参照を変更しても、の参照は変更されないため、同じ古い文字列を指します。aC.a"a"aC.abC.b

于 2013-03-09T17:46:13.310 に答える
3

あなたを混乱させているのは、あなたが考えていることです

aC.a += "a";

によって参照される String オブジェクトの状態を変更しますaC.a。そうではありません。文字列は不変であり、上記のコード行は新しい String オブジェクトを作成して aC.a に割り当て、元のオブジェクトへの他のすべての参照をそのまま残します。

StringBuilder、および呼び出しで同じテストを行います

aC.a.append("a");

すると、別の結果が得られます。

于 2013-03-09T17:48:53.737 に答える
1

JVM には 3 つの文字列オブジェクトがあります。"aaa"、"a"、"aaaa" (文字列は不変であるため)。最初、aC.a と bC.b は同じ文字列オブジェクト「aaa」を指していました。この行で aC.a += "a"; コードは aC.a の参照を「aaaa」を指すように変更しています。これで aC.a -> "aaaa" と bC.b -> "aaa" になりました。私がはっきりしていることを願っています。

于 2013-03-09T18:43:25.953 に答える
0

Java は実際には参照値渡しです。実際の参照がコピーされ、そのコピーが関数に送信されます。

于 2013-03-09T17:46:52.613 に答える