1

私のJavaプログラムがどのようにメモリを割り当てているかについて少し混乱しています。以下は私のプログラムの典型的な状況です。クラス内のヒープ上に作成されたオブジェクトがあり、それを他のクラス内の他の関数に渡します。

public class A {
    private List<Integer> list = new ArrayList<Integer>();

    public A() {
        for(int i = 0; i < 100; i++)
            list.add(i);
    }

    public void foo() {
        B b = new B();
        b.bar(this.list);
    }
}

public class B {
    A a = new A();

    public int bar(List<Integer> list) {
        list.add(-1);
        return list.size();
    }

    public int getSize() {
        List<Integer> list = a.list;
        return a.size();
    }
}

私の質問は、メモリがどのように使用されているかについてです。AのリストがB.bar()に渡されると、メモリはコピーされますか?Javaは値渡しであるため、B.bar()関数には、ヒープにも割り当てられているリストのコピーが含まれていると思いますか?それとも、リストを複製してスタックに配置しますか?それとも、リストがまったく重複していますか?同様に、B.getSize()内のこれらのメモリの質問には何が当てはまりますか?

4

3 に答える 3

8

Javaでは、オブジェクト参照は値によって渡されると言った方がおそらく明確です。

したがって、Bはリストへの参照(値)のコピーを取得しますが、リスト自体のコピーは取得しません。

Bにリストを変更させ(何かを追加または削除することによって)、Aのリストも変更される(つまり、同じリストである)ことを確認することで、これを簡単に証明できます。

ただし、リストへのBの参照を変更した場合(新しいリストを作成して割り当てることにより)、Aの参照は変更されません。

于 2012-11-23T23:56:50.480 に答える
3

Javaは値渡しですが、式または変数の値は常にプリミティブまたは参照のいずれかです。次に、参照はnullまたはオブジェクトへのポインタのいずれかです。

あなたの場合:private List<Integer> list = new ArrayList<Integer>();listを参照型として宣言し、その値を新しく割り当てられたArrayListオブジェクトへのポインターにします。

listたとえば呼び出しで実際の引数として使用する場合b.bar(this.list);、b.barの仮引数リストはそのポインターのコピーで初期化されます。つまり、barの仮引数は、作成されたAと同じArrayListオブジェクトを指します。ArrayListオブジェクトはコピーされません。

于 2012-11-24T00:02:25.780 に答える
1

Javaは値渡しです、くそっ!

ただし、オブジェクトへの参照にしかアクセスできません。その意味で、オブジェクト参照を値で渡します

于 2012-11-23T23:59:57.327 に答える