Java パラメータは値で渡されるべきですか、それとも参照で渡されるべきですか?この質問は非常に基本的なものですが、多くの人が少し混乱しています。
最初にパラメータに関するいくつかの概念を理解する必要があります
仮パラメータ: 関数を定義するときに使用されるパラメータは、関数によって渡されるパラメータを受け取るために使用されます。たとえば、関数を作成する場合、関数内のパラメータは仮パラメータです。
public void test(String str) { //str为形式参数 System.out.println(str); }
実際のパラメータ: 関数 When を呼び出します。関数名の後の括弧内のパラメータは実パラメータと呼ばれ、次の例に示すように、明確な値を持つ必要があります。
public static void main(String[] args) { A a = new A(); a.test("小 明"); //"小 明"则为实际参数 }
それは、 when であることがわかります。パラメータ化された関数が呼び出されると、実際のパラメータが仮パラメータに渡されます。
この種の受け渡しプロセスにおけるパラメーターには、通常、値の受け渡しと参照の受け渡しという 2 つの状況があります。
をコピーして関数に渡します。関数内のパラメータを変更しても、実際のパラメータには影響しません。パラメータ、つまり はコピーを作成します。これはネイティブ オブジェクトには影響しません。
と 参照データ型 があります。ただし、8 つの基本データ型を除く、すべての参照データ型、つまり byte、short、int、long、char、boolean、float、doubleJava は値渡しですか、それとも参照渡しですか?
渡されるパラメータの種類: 基本データ型
public class TestBasic { public static void main(String[] args) { int num1 = 10; int num2 = 20; change(num1, num2); System.out.println("=============="); System.out.println("num1 = " + num1); System.out.println("num2 = " + num2); } public static void change(int param1, int param2) { System.out.println("param1 = " + param1); System.out.println("param2 = " + param2); param1 = 333; param2 = 444; System.out.println("after change...."); System.out.println("param1 = " + param1); System.out.println("param2 = " + param2); } }
param2 = 20基本的なデータ型はメモリ内に 1 つの記憶領域しかなく、変更後....
change() メソッドで変数を再割り当てしても、変数 num1 と num2 の値は変更されないことがわかります。 #変更されるのは、change() メソッド内の num1 と num2 のコピーのみです。
param1 = 333
param2 = 444
==============
num1 = 10
num2 = 20
スタック に割り当てられることを知っておく必要があります。 Java パラメータの型が基本データ型の場合、値によって渡されます
。
パラメータの種類: 参照データ型
public class TestQuote { public static void main(String[] args) { String str = "小明"; StringBuilder str2 = new StringBuilder("今天天气好"); change(str,str2); System.out.println("=============="); System.out.println("str = " + str); System.out.println("str2 = " + str2); } public static void change(String param1,StringBuilder param2) { System.out.println("param1 = " + param1); System.out.println("param2 = " + param2); param1= "小张"; param2.append(",我们去钓鱼"); System.out.println("after change...."); System.out.println("param1 = " + param1); System.out.println("param2 = " + param2); } }結果:
param1 = Xiao Ming
param2 = 今日天気は良いです変更後....またはparam1 = Xiao Zhang
値を渡す
param2 = 今日は天気が良いので、釣りに行きましょう
str = Xiao Ming
str2 = 今日は天気が良いので釣りに行きましょう
str 変数は変更されていませんが、str2 変数は変更されていることがわかりました。混乱していますか: Java パラメータの受け渡しの型が参照である場合データ型は、
参照によって渡される ですか? 実際、誰もがたくさんの用語に騙されています。著者は誰もが理解できるように 2 つの絵を描きました:
beforechange():after change():
Java では、基本的なデータ型を除き、その他は参照型です。参照型にはメモリ内に 2 つの記憶領域があります。 1 つのピースはスタック内にあり、1 つのピースはヒープ内にあります)。
パラメータが参照型の場合、スタック上にある実パラメータが参照するオブジェクトのアドレス値のコピーが渡されます。ここで作成されるコピーはアドレスのコピーです。そしたら誰かが言っていましたが、値が変わってしまいました、これは明らかに「参照渡し」なのでしょうか? 別の観点から理解すると、スタックアドレスを値として扱うと、スタックアドレスのコピーが作成される(スタックフレームをコピーする)ことになり、スタックアドレスは最終的には変化せず、ただし、ヒープメモリ内の値は変化します。スタックアドレスが鍵のようなもので、それをコピーすれば金庫を開けることができます。気にするのは鍵の模様に変化がないかどうかであり、金庫を開けた後の金額については気にする必要はありません。 関数を呼び出した後、str2 変数の値 (ヒープ内のデータ) は変更されましたが、パラメーターは参照型であり、実際に渡されるパラメーターはスタック内のアドレス値です。スタックはコピーされますが、最終スタックのアドレス値は変更されていません。したがって、コピーの作成は値転送
の定義に準拠し、元のオブジェクトには影響しません。なぜ str 変数の値が変わらないのかと、もう一度尋ねる人もいるかもしれません。実際、これは完全に String クラス
の特殊な性質によるものです。これが不変で最終的なものであることはわかっています。このとき、関数内の param1= "Xiao Zhang"; は実際に新しいクラスを作成します。暗黙的に文字列オブジェクトを作成し、同時にヒープ 新しいメモリ空間がメモリ内に開かれ、param1 はこの新しく開かれたメモリ空間を指します。元のアドレス str が指すヒープ メモリ空間内のデータは変更されません。以上がJava でのみ値が渡されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。