1. ホーム

[解決済み】Javaで配列は値で渡されるのか、参照で渡されるのか?[重複しています。]

2022-04-07 10:31:48

質問

配列は プリミティブ型 は、Javaでは はオブジェクトでもない ということは、値で渡されるのか、参照で渡されるのか?配列が何を含むかによって、例えば参照やプリミティブ型が変わるのでしょうか?

どのように解決するのですか?

あなたの質問は、誤った前提に基づいています。

<ブロッククオート

配列はJavaのプリミティブ型ではありませんが、オブジェクトでもありません ... "

実際、Javaのすべての配列は オブジェクト 1 . すべての Java 配列タイプには java.lang.Object のすべてのメソッドの実装を継承しています。 Object APIを使用します。

...で、それらは値で渡されるのか、参照で渡されるのか?配列が何を含むかによって、例えば参照やプリミティブ型が異なるのでしょうか?

短く答えてください。1)値で合格、2)差はない。

長文です。

すべてのJavaオブジェクトと同様に、配列は値で渡されます... しかし、値は配列への参照です。 したがって、呼び出されたメソッドで配列のセルに何かを代入すると、呼び出し元が見ているのと同じ配列オブジェクトに代入することになります。

これは参照渡しではありません。 リアル 参照渡しでは 変数のアドレス . とは リアル 参照渡しでは、呼び出されたメソッドはそのローカル変数に代入することができ、これによって呼び出し側の変数が更新されることになります。

しかし、Javaではそうではない。 Javaでは、呼び出されたメソッドは配列の内容を更新でき、配列参照のコピーも更新できますが、呼び出し側の配列参照を保持する呼び出し側の変数を更新することはできないのです。 したがって......Javaが提供するものは参照渡しではありません。

参照渡しと値渡しとの違いを説明したリンクはこちらです。 上記の私の説明が理解できない場合、あるいは用語に異論があると感じる場合、あなたは べきである を読んでみてください。

関連するSOの質問です。

歴史的な背景

pass-by-referenceは元々call-by-referenceで、FORTRANの引数渡しセマンティクス(call-by-reference)とALGOL-60のそれ(call-by-value, call-by-name)を区別するために使われた言葉であった。

  • call-by-valueでは、引数式は値として評価され、その値は呼び出されたメソッドにコピーされます。

  • 参照渡しの場合、引数式の一部が評価され、呼び出し側のメソッドに渡される "lvalue" (つまり、変数または配列要素のアドレス)が作成されます。 呼び出し側のメソッドは、その変数や要素を直接読み込んで更新することができます。

  • call-by-nameでは、実際の引数式は呼び出し側のメソッドに渡され(!!)、そのメソッドはそれを複数回評価することができます(!!)。 これは実装が複雑で、非常に理解しにくいコードを書くために使われる(悪用される)可能性がありました。 call-by-nameはAlgol-60でしか使われなかった(ありがたいことだ!)。

アップデイト

実は、Algol-60のcall-by-nameは、ラムダ式をパラメータとして渡すのに似ている。 このラムダ式は、実装レベルではサンクと呼ばれていました。 それとなく 呼び出したプロシージャ/関数のスコープ内にある変数の状態を変更する。 これが、この関数を理解しにくくしている要因の一つです。 (Wikipediaの ジェンセンの装置 などがある)


1. リンク先のQ&Aには何も書かれていない( Javaにおける配列とそのメモリへの格納方法 ) は、配列がオブジェクトではないことを述べているか、暗に示している。