Java で値によって渡される配列または参照によって渡される配列
このチュートリアルでは、Java で値または参照によって渡される配列を紹介します。
メソッドを呼び出すとき、その引数は値または参照として渡すことができます。これらの両方について説明する前に、2つの用語を理解しましょう。
callee
:これは別のメソッドによって呼び出されたメソッドですcaller
:これは別のメソッドを呼び出すメソッドです
ここで、値渡しと参照渡しの意味を学びましょう。
Java で値によって渡されるもの
引数が値で渡されると言うと、実際のパラメータの値のコピーがメモリに作成されます。
呼び出し元と呼び出し先は、同じ値を持つ 2つの独立変数を維持します。呼び出し先がパラメーター値を変更した場合、呼び出し元の変更を確認できません。
重要なポイント:
- 呼び出し先は、呼び出し元のコードの元の要素にアクセスできません。
- データ(パラメータ値)のコピーが呼び出し先に送信されます。
- 渡された変数を変更しても、最終的な値には影響しません。
Java で参照によって渡されるもの
引数が参照によって渡される(アドレスによる受け渡しとも呼ばれる)とは、呼び出し元の関数の引数の参照を対応する仮パラメーターに渡すことを意味します。
この状況では、実際の引数のアドレスのコピーが作成されます。呼び出し元と呼び出し先はパラメーターに同じ変数を使用するため、呼び出し先がパラメーター変数を変更すると、呼び出し元の変数の変化を確認できます。
重要なポイント:
- Callee は、呼び出し元のコードでプログラミング要素への参照を提供します。
- 値の代わりに、保存されたデータのメモリアドレスが渡されます。
- 値を変更すると、元のデータに影響します
Java は値によって渡されます
C++ とは異なり、Java では、引数は値としてのみ渡すことができます。ただし、落とし穴があります。オブジェクトが引数として渡されると、オブジェクトの参照が値として呼び出し先に渡されます。
つまり、Java は厳密に値によって渡されますが、オブジェクトの参照によって渡されたように動作します。この概念をよりよく理解するために、いくつかの例を使用してみましょう。
Java でプリミティブデータ型を渡す
以下のコードでは、関数の引数として 2つの整数を渡し、それらの値を変更します。
Java では引数は値によって渡されるため、関数は引数の個別のコピーを保持します。引数に加える変更は、関数のコピーでのみ行われ、メイン関数(呼び出し元)が維持するコピーでは行われません。
したがって、関数呼び出しの終了後に値を出力すると、元の値が取得されます。以下のサンプルコードを見てください。
public class SimpleTesting {
static void JE_function(int n1, int n2) {
n1 = -232;
n2 = -90;
}
public static void main(String args[]) {
int JE_numa = 6932;
int JE_numb = 8934;
System.out.println("Numbers before function call :" + JE_numa + " and " + JE_numb);
JE_function(JE_numa, JE_numb);
System.out.println("Numbers after the JE_function call :" + JE_numa + " and " + JE_numb);
}
}
出力:
Numbers before function call:6932 and 8934
Numbers after the JE_function call:6932 and 8934
Java で配列を渡す
オブジェクトに関しては、オブジェクトへの参照は引数として値によって渡されます。
以下のコードでは、引数として配列を渡し、オブジェクト(配列)の値を出力すると、メモリ位置が出力されます。これは、オブジェクト変数がオブジェクトが格納されているメモリの場所を格納しているという事実と関係があります。
以下のサンプルコードを見てください。
public class SimpleTesting {
static void JE_function(String[] sentence) {
System.out.println(sentence);
}
public static void main(String args[]) {
String[] sent = {"I", "Love", "Delftstack"};
JE_function(sent);
}
}
出力:
[Ljava.lang.String;@442d9b6e
上記のコードを使用して、引数として渡された配列への参照を伝達しようとします。したがって、(メモリ位置ではなく)配列の値を変更すると、その変更は呼び出し先に反映されます。
以下のサンプルコードを見てください。
public class SimpleTesting {
static void JE_function(String[] sentence) {
sentence[1] = "Visit";
}
public static void main(String args[]) {
String[] sent = {"I", "Love", "Delftstack"};
System.out.println("Sentence before calling the function");
for (String word : sent) {
System.out.println(word);
}
JE_function(sent);
System.out.println("Sentence after calling the function");
for (String word : sent) {
System.out.println(word);
}
}
}
出力:
Sentence before calling the function
I
Love
Delftstack
Sentence after calling the function
I
Visit
Delftstack
上記のコードからわかるように、配列への変更はメインブロックに反映されます。
2 人の友人がプロジェクトに取り組んでいるかのように考えてください。友人の 1 人が行う作業はすべて、プロジェクト全体に反映されます。
この場合、関数はメインブロックが使用するのと同じ配列を参照します。