Javaでは、配列は値で渡されますか、それとも参照で渡されますか?[複製]

198
Froskoy 2012-10-06 21:44.

重複の可能性:
Javaは「参照渡し」または「値渡し」ですか?

配列はJavaのプリミティブ型はありませんが、オブジェクトでもないので、値または参照によって渡されますか?参照やプリミティブ型など、配列に含まれるものに依存しますか?

7 answers

143
Stephen C 2012-10-06 21:47.

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

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

実際、Javaのすべての配列オブジェクト1です。すべてのJava配列型はjava.lang.Object、そのスーパータイプとして持ち、ObjectAPIのすべてのメソッドの実装を継承します。

...では、値または参照によって渡されますか?参照やプリミティブ型など、配列に含まれるものに依存しますか?

簡単な答え:1)値を渡す、2)違いはありません。

長い答え:

すべてのJavaオブジェクトと同様に、配列は値によって渡されます...ただし、値は配列への参照です。したがって、呼び出されたメソッドで配列のセルに何かを割り当てると、呼び出し元に表示されるのと同じ配列オブジェクトに割り当てられます。

これは参照渡しではありません。 実際の参照渡しには、変数のアドレスを渡すことが含まれます。では、実際の参照渡し、呼び出されたメソッドは、そのローカル変数に割り当てることができ、これは、呼び出し元で変数が更新されます。

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

参照渡しと値渡しの違いを説明するリンクをいくつか示します。上記の私の説明を理解していない場合、または用語に同意できないと感じた場合、それら読む必要があります。

関連するSOの質問:

歴史的背景:

「pass-by-reference」というフレーズは元々「call-by-reference」であり、FORTRAN(call-by-reference)の引数受け渡しセマンティクスとALGOL-60(call-by-value)のセマンティクスを区別するために使用されました。および名前による呼び出し)。

  • 値による呼び出しでは、引数式が値に評価され、その値が呼び出されたメソッドにコピーされます。

  • 参照による呼び出しでは、引数式は、呼び出し元のメソッドに渡される「左辺値」(つまり、変数または配列要素のアドレス)に部分的に評価されます。呼び出し元のメソッドは、変数/要素を直接読み取って更新できます。

  • 名前による呼び出しでは、実際の引数式が呼び出し元のメソッド(!!)に渡され、呼び出し元のメソッドはそれを複数回評価できます(!!!)。これは実装が複雑で、理解するのが非常に難しいコードを書くために使用(悪用)される可能性がありました。名前による呼び出しは、Algol-60でのみ使用されていました(ありがたいことに!)。

更新

実際、Algol-60の名前による呼び出しは、ラムダ式をパラメーターとして渡すことに似ています。しわは、これらの正確ではないラムダ式(実装レベルでは「サンク」と呼ばれていました)が、呼び出し元のプロシージャ/関数のスコープ内にある変数の状態を間接的に変更できることです。それが彼らを理解するのをとても難しくした理由の一部です。(たとえば、ジェンセンのデバイスに関するウィキペディアのページを参照してください。)


1.リンクされたQ&A(Javaの配列とそれらがメモリに格納される方法)には、配列がオブジェクトではないことを述べたり暗示したりするものはありません。

267
Rohit Jain 2012-10-06 21:47.

Everything in Java are passed-by value.。Array(これはオブジェクトに他なりません)の場合、配列参照は値によって渡されます。(オブジェクト参照が値によって渡されるのと同じように)。

配列を他のメソッドに渡すと、実際にはその配列への参照がコピーされます。

  • その参照による配列の内容の変更は、元の配列に影響します。
  • ただし、新しい配列を指すように参照を変更しても、元のメソッドの既存の参照は変更されません。

この投稿を参照してください。

Javaは「参照渡し」または「値渡し」ですか?

この作業例を参照してください:-

public static void changeContent(int[] arr) {

   // If we change the content of arr.
   arr[0] = 10;  // Will change the content of array in main()
}

public static void changeRef(int[] arr) {
   // If we change the reference
   arr = new int[2];  // Will not change the array in main()
   arr[0] = 15;
}

public static void main(String[] args) {
    int [] arr = new int[2];
    arr[0] = 4;
    arr[1] = 5;

    changeContent(arr);

    System.out.println(arr[0]);  // Will print 10.. 

    changeRef(arr);

    System.out.println(arr[0]);  // Will still print 10.. 
                                 // Change the reference doesn't reflect change here..
}
61
Tudor 2012-10-06 21:46.

配列は実際にはオブジェクトであるため、参照が渡されます(参照自体は値によって渡されますが、まだ混乱していますか?)。簡単な例:

// assuming you allocated the list
public void addItem(Integer[] list, int item) {
    list[1] = item;
}

呼び出し元のコードからリストへの変更が表示されます。ただし、参照自体は値で渡されるため、変更することはできません。

// assuming you allocated the list
public void changeArray(Integer[] list) {
    list = null;
}

null以外のリストを渡した場合、メソッドが戻るまでにnullにはなりません。

13
sakthisundar 2012-10-06 21:47.

いいえ、それは間違っています。配列はJavaの特別なオブジェクトです。つまり、参照自体ではなく、参照の値を渡す他のオブジェクトを渡すようなものです。つまり、呼び出されたルーチンで配列の参照を変更しても、呼び出し元のルーチンには反映されません。

4
aleroot 2012-10-06 21:49.

Javaのすべては値によって渡されます。

配列の場合、参照は新しい参照にコピーされますが、Javaのすべてが値によって渡されることに注意してください。

詳細については、この興味深い記事をご覧ください...

2
Steven McGrath 2012-10-06 22:51.

配列の決定的な議論はhttp://docs.oracle.com/javase/specs/jls/se5.0/html/arrays.html#27803にあります。これにより、Java配列がオブジェクトであることが明確になります。これらのオブジェクトのクラスは10.8で定義されています。

言語仕様のセクション8.4.1、http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#40420では、引数がメソッドに渡される方法について説明しています。Java構文はCとC ++から派生しているため、動作は似ています。プリミティブ型は、Cと同様に値で渡されます。オブジェクトが渡されると、オブジェクト参照(ポインター)は値で渡され、ポインターを値で渡すC構文を反映します。4.3.1、http: //docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.3を参照してください。

実際には、これは、メソッド内の配列の内容の変更が呼び出しスコープ内の配列オブジェクトに反映されることを意味しますが、メソッド内の参照に新しい値を再割り当てしても、呼び出しスコープ内の参照には影響しません。これは、Cの構造体またはC ++のオブジェクトへのポインタに期待される動作とまったく同じです。

用語の混乱の少なくとも一部は、Cが一般的に使用される前の高級言語の歴史に起因します。以前の人気のある高級言語では、アドレスによってメモリを直接参照することは、可能な限り避けるべきものでした。抽象化レイヤーを提供する言語の仕事と見なされていました。このため、言語はサブルーチンから値を返すメカニズムを明示的にサポートする必要がありました(必ずしも関数である必要はありません)。このメカニズムは、「参照渡し」を参照するときに正式に意味されるものです。

Cが導入されたとき、すべての引数が入力専用であり、呼び出し元に返される唯一の値が関数の結果である、プロシージャ呼び出しの概念が削除されました。ただし、参照を渡す目的は、ポインターを明示的かつ幅広く使用することで実現できます。同じ目的を果たすため、値への参照としてポインタを渡す方法は、口語的に参照による受け渡しと呼ばれることがよくあります。ルーチンのセマンティクスがパラメーターを参照によって渡すことを要求する場合、Cの構文では、プログラマーが明示的にポインターを渡す必要があります。ポインターを値で渡すことは、Cで参照渡しのセマンティクスを実装するためのデザインパターンです。

Cのrawポインタの唯一の目的はクラッシュするバグを作成することであるように思われることが多いため、その後の開発、特にJavaは、パラメータを渡すためのより安全な手段に戻ろうとしました。ただし、Cの優位性により、開発者はおなじみのCコーディングのスタイルを模倣する必要がありました。その結果、ポインタと同様に渡される参照が作成されますが、より安全にするために、より多くの保護が実装されています。代替案は、A​​daのような言語の豊富な構文でしたが、これは、歓迎されない学習曲線の外観を示し、Javaの採用の可能性を減らしました。

要するに、Javaでの配列を含むオブジェクトのパラメーター受け渡しの設計は、本質的には参照による受け渡しのセマンティックな意図を果たすためのものですが、値による参照の受け渡しの構文で実装されています。

0
Jeff Watkins 2012-10-06 21:48.

一種のトリックリアル...参照でさえJavaでは値によって渡されるため、参照自体への変更は呼び出された関数レベルでスコープされます。コンパイラやJVMは、多くの場合、値型を参照に変換します。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

HMSプリンスオブウェールズの橋はスターウォーズからまっすぐです

HMSプリンスオブウェールズの橋はスターウォーズからまっすぐです

BAE Systems Maritimeは昨日、英国海軍の2番目のクイーンエリザベスクラスの空母であるHMSプリンスオブウェールズのブリッジモジュールを展開しました。公海を航海するよりも、アウターリムの惑星を周回してタイファイターを発射する必要があるようです。70,000の排水量のトン運搬船は、2020年に就役し、姉のエリザベス女王と同様に、約40機の航空機を運ぶ予定です。

ルイビルはサヨナラゲームでウェイクフォレストを倒すために家を盗んだ

ルイビルはサヨナラゲームでウェイクフォレストを倒すために家を盗んだ

ルイビルは、通常の大学野球の強みであるピッチング、ディフェンス、スマートベースランニングを通じて、全国ランキングのトップ5と19-2の会議記録への道を歩みました。昨夜、彼らは野球の最もエキサイティングなプレーの1つである盗塁を使用して、ウェイクフォレストのスイープを完了しました。

おいしいツイストのためにコーンブレッドであなたの次のサンドイッチを作りましょう

おいしいツイストのためにコーンブレッドであなたの次のサンドイッチを作りましょう

粗いパン粉とふわふわの食感のコーンブレッドは、唐辛子を吸い上げるのに理想的な乗り物です。しかし、それだけではありません。

別の驚くべきマーベルヒーローがキャプテンアメリカに参加します:シビルウォー!

別の驚くべきマーベルヒーローがキャプテンアメリカに参加します:シビルウォー!

ニール・ブロムカンプが、チャッピーが第10地区をどのように遅らせたのかについて話します。フォースの覚醒の噂は、次の予告編に何を期待するかについてのいじめを提供します。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language