2012-02-22 20 views
1

可能性の重複:
Is Java pass by reference?Javaのメモリ、パス・バイ・バリュー、参照渡し

私は値渡しとJavaで参照渡しについて質問があります。

私は、グラフとして長いdouble型の配列を表示するために書いた "Graph"クラスを持っています。(単純化された)コンストラクタは、次のようになります。

private double[] Values; 

public Graph(double[] values) { 
    Values = values; 
} 

このアレイはかなり長くなり、妥当な量のメモリを占有します。

私の質問はこれです:コンストラクタを呼び出して新しいグラフを作成すると、配列 "Values"は渡された配列のコピーになりますか、それとも参照になりますか?

私の考えでは、プリミティブは「値渡し」で、オブジェクトは「参照渡し」です。これは配列がコピーであることを意味します。私はこの定義が技術的に正しいとは思っていませんが。

私が正しく、配列がコピーである場合、このクラスが使用するメモリ量を減らし、別のクラスから配列を参照するにはどうすればよいでしょうか? 抽象GetValues()メソッドはこれを実現する良い方法でしょうか?

ありがとうございます。

Chris。

+2

Javaは=値渡し。 http://stackoverflow.com/questions/40480/is-java-pass-by-reference – Alfabravo

+6

Javaは「値によって参照を渡す」。 –

+1

低レベルのC言語でのjavaの受け渡しについて考える場合、最適なものは 'const Object *'です。これは定数オブジェクトへのポインタです。それを参照から外すことをお勧めします - それは既にC++用語で定義されているので、ちょうど混乱しており、javaとはまったく異なります。 – Voo

答えて

6

doubleはプリミティブ型ですが、double[]はObject型(配列)なので、いいえ、配列全体がコンストラクタに渡されず、代わりに配列が "参照の値"として渡されます。コンストラクタ内で配列を置き換えることはできませんが、必要に応じて配列の個々の値を置き換えることができます。

+1

まだ参照していないことに注意してください。参照渡しの場合、スワップメソッドを実装できます。これはjavaではまったく動作しません。 – Voo

+0

当然、これは「値による参照」です –

+2

これで、「参照」をポインタの同義語として使用しています。それはここではまったく異なる定義で用語を再利用しているという問題です。 – Voo

2

valuesの参考になります。 Javaは値渡しですが、値が渡されるのは、配列がオブジェクトなので、配列への参照です。

また、ほんの数日前からthis answerも参照してください。

0

参考になります。パラメータvaluesは「値による参照」が渡され、参照はValuesに関連付けられます。

このように、Graph.Valueまでの任意の数値は、valuesに反映され、逆も同様です。

4

Javaは、値渡しの期間です。

メソッドのパラメータ(§8.4.1)メソッドに渡された名前の引数値:

JLS4.12.3 Kinds of Variablesを参照してください。メソッド宣言で宣言されたすべてのパラメータに対して、そのメソッドが呼び出されるたびに新しいパラメータ変数が作成されます(15.12)。新しい変数は、メソッド呼び出しからの対応する引数値で初期化されます。メソッド本体は、メソッドの本体の実行が完了すると、事実上存在しなくなります。

EDIT:私の答えを明確にする:プリミティブと参照型:ジャワの種類は、次の2つのカテゴリに分かれています。メソッド(またはコンストラクタ)を呼び出すたびに、パラメータがコピーされます(Javaは値渡しであるため)。プリミティブは完全にコピーされ、参照型の場合は参照がコピーされます。Javaは何も自動的にディープコピーすることはありません。そのため、配列は参照型なので、配列への参照だけがコピーされます。

+0

オブジェクトの参照が値渡しと言うことがあります。これは、オブジェクト自体が参照渡しされるという効果があります。 – phlogratos

+3

@phlogratosそうですか?それから 'swap(Object a、Object b)'メソッドを書いてください。それは基本的に、参照渡しのリトマステストです。 – Voo

+1

-1。 "あなたがコンストラクタを呼び出した場合、配列はコピーであるのか、それとも参照になるのでしょうか?"という本質的な質問には答えませんが、答えは "コピー"です。技術的に正しい)。配列ではなく参照をコピーしています。 – ILMTitan

0

アレイは、アレイではないプリミティブ型、に適用されるコピー渡し、参照型あります。他の参照型は、方法によってクラスインターフェースを含みます。

0
// Points: 
// 1) primitive variables store values 
// 2) object variables store addresses(location in the heap) 
// 3) array being an object itself, the variables store addresses again (location in the heap) 

// With primitives, the bit by bit copy of the parameters, results in the 
// value being copied. Hence any changes to the variable does not propagate 
// outside 
void changePrimitive(int a) { 
    a = 5; 
} 

// With objects, the bit by bit copy of the parameters, results in the address 
// begin copied. Hence any changes using that variable affects the same object 
// and is propogated outside. 
class obj { 
    int val; 
} 
void changeObject(obj a) { 
    a.val = 10; 
} 

// Array is itself an object which can hold primitives or objects internally. 
// A bit by bit copy of the parameters, results in the array's address 
// being copied. Hence any changes to the array contents reflects in all 
// the locations having that array. 
void changeArray(int arr[]) { 
    arr[0] = 9; 
    arr[1] = 8; 
} 

// NOTE: when object/array variable is assigned a new value, the original 
// object/array is never affected. The variable would just point to the 
// new object/array memory location. 
void assignObj(obj a) { 
    a = new obj(); 
    a.val = 10; 
}