トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

Javaの参照とかコピーとか

[Java]

Javaの参照とかコピーとか

  • 業務アプリを作るうえで興味深い内容なのでちょっと翻訳します。
pass by value, call by value
日本語では「値渡し」
call by reference
日本語では「参照渡し」
HashMap内部にある値の変更はHashMap内部を変更するのか?
→ 変更されます

  HashMap内部にある値の変更はHashMap内部を変更するのか?

Changing value after it's placed in HashMap changes what's inside HashMap?

Diegoの質問

If I create a new HashMap and a new List,

and then place the List inside the Hashmap with some arbitrary key and

then later call List.clear() will it affect what I've placed inside the hashmap?

The deeper question here being: When I add something to a hashmap,

is a new object copied and placed or is a reference to the original object placed?

Thanks!

新しいHashMapやListを作ったとしましょう、
次に任意のキーを使用してHashMap内部にListを配置しList.clear()を呼び出します。
そうした場合HashMap内部にはどのような効果があるでしょうか?

ここには深い問いがあります:というのは何かをHashMap内部に加えた場合
それはコピーされた新しいオブジェクトなのか?それとももともと存在したオブジェクトの参照
なのかということです。

よろしく!

Scott Stanchfieldの回答

What's happening here is that you're placing a pointer to a list in the hashmap, not the list itself.

When you define

List<SomeType> list;

you're defining a pointer to a list, not a list itself.

When you do

map.put(somekey, list);

you're just storing a copy of the pointer, not the list.

If, somewhere else, you follow that pointer and modify the object at its end, anyone holding that pointer will still be referencing the same, modified object.

Please see http://javadude.com/articles/passbyvalue.htm for details on pass-by-value in Java.

ここで起こっていることはまさにHashMap内部のリストにポインタを置いているということであり、リストそのものではないのです。
あなたが、
List<SomeType> list;
と定義した場合

あなたはリストへのポインタを定義したに過ぎず、リストそのものを定義したことにはならないのです。

もしあなたが
map.put(somekey, list);
と書いた場合、これはポインタのコピーを保存したにすぎません、リストではないのです。

もし、他のどこかでそのポインタを引き継ぎ、オブジェクトの内容を変更した場合、ポインタはいまだに同じものを
参照しているので、オブジェクトは変更されます。

Javaにおける値渡しの詳細については以下のリンクを参照してください。
http://javadude.com/articles/passbyvalue.htm

stavrosのサンプルコード

[http://stackoverflow.com/a/2728319]

日本語訳してwandboxで動くようにした。http://melpon.org/wandbox/permlink/h2ihhnH6w7SAZVXC

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

class Foo {
    public Foo(int id, String name) {
        this.id=id;
        this.name=name;
    }

    public static void main(String[] args) {
        HashMap strs = new HashMap();

        // オブジェクトのリストを作成する
        List ls = new ArrayList();
        ls.add(new Foo(1, "Stavros"));
        ls.add(new Foo(2, "Makis"));
        ls.add(new Foo(3, "Teo"));
        ls.add(new Foo(4, "Jim"));

        // リストからハッシュマップへの参照をコピーする
        strs.put("1", ls.get(0));
        strs.put("2", ls.get(1));
        strs.put("3", ls.get(2));
        strs.put("4", ls.get(3));

        System.out.println("list before change  : " + ls);
        System.out.println("map before change   : " + strs);
        // ハッシュマップからオブジェクトを取得する
        Foo f = (Foo)strs.get("1");
        // 異なる値を設定する
        f.setId(5);
        // 違いがリストからハッシュマップへ反映されたことを監視する
        System.out.println("list after change   : "+ls);
        System.out.println("map after change    : "+strs);
    }

    private int id;
    public void setId(int id) {
        this.id=id;
    }
    public int getId() {
        return this.id;
    }

    private String name;
    public void setName(String name) {
        this.name=name;
    }
    public String getName() {
        return this.name;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(id);
        sb.append("-");
        sb.append(name);
        return sb.toString();
    }
}

お名前: コメント: