━目次━






まず最初に言っておきますが、Javaに参照渡しは存在しません

これ聞いたとき私も「えっ!」ってなりました。


いやいや、参照渡し使ってましたよ自分。

え?それは本当の参照渡しじゃなくて参照の値渡し? ん??


それから色々調べて「おもしれー!!」ってなったのでまとめます。

このページを読み終わる頃にはあなたも「おもしれー!!」ってなっているはずです。

まずは値(プリミティブ)型と参照型について

そもそも値型参照型を知らない人は。それ以外の人は読み飛ばして結構です。

値(プリミティブ)型とは

値型は以下の8つです。

boolean 1bit
byte 8bit
char 16bit
short 16bit
int 32bit
float 32bit
long 64bit
double 64bit

値型のイメージはあなたがフタの空いた段ボールを持っていて、その中に値を入れているイメージです。

実際にそこに値があります。

参照型とは

参照型はそれ以外の変数たちで、よく使うとこだと

String
配列
List系
DtoやFormなどのクラス etc…


などですね。

初学者は『参照型』と聞くともうそれだけで蕁麻疹が出る程に脳が拒否する人もいますね。

考える人考える人

分かるわ~わしもそうじゃ

でも実はそんなに難しくなくて、イメージとしてはロッカーの鍵を持っているイメージです。

実際に値が格納されているのはロッカーの中で、あなたはそのロッカーの番号が書かれた鍵を持っているだけなんです。

まずはざっくりとこのイメージを持っておいてください。

値渡しと参照渡しの違いについて(Javaとか関係なく)

ではJavaのことは1回忘れて俗に言う『値渡し』『参照渡し』とは何ぞやということですが、

『渡し』と言うくらいなのでファンクションなどに変数(値型or参照型)を渡すときの話です。

まずはソースを見る前に↓のイメージをしてください。
(経験上イメージする前にソースを見ると思考が止まるので…)

【値渡しの場合】
あなたは段ボールを持ったまま中の値を確認してファンクション君に伝えます。

※あくまで伝えるだけです。段ボール大好き人間のあなたは段ボールを手放しません。

【参照渡しの場合】
あなたはロッカーの鍵をファンクション君に渡しちゃいます。

※ファンクション君を相当信用しているんでしょう。ロッカーの中身は好き放題いじられます。

じゃけぇじゃけぇ

じゃあこのイメージでソースを見てみよう。

【値渡しの動作】


ファンクションを呼び出す際に、段ボールの中身を伝えているだけなので、iの値がファンクションを呼び出した後も変わってないことが分かります。
段ボールフェチですからね。

【参照渡しの動作】

※後述しますがJavaには正確な参照渡しは存在しません!しかし↓のソースなら参照渡しっぽく動くのでまずは雰囲気を掴むために便宜上「参照渡し」として説明しています。


鍵そのものをファンクションに渡しているので、ロッカーの中は自由にいじられ中身が変わります。

ロッカーの中を確認(println)したら優しいファンクション君がカンペを入れてくれてました。これでテストは無敵だ。

これが一般的な値渡しと参照渡しの動作の違いです。

考える人考える人

なるほど~よし!大体Javaのこと分かったけぇもう帰るわ!ありがと!

じゃけぇじゃけぇ

まてまて(笑)ここからがJava特有の面白いところなんだから

考える人考える人

あ?そうなん?(笑)

Javaは参照渡しではなく参照の値渡し

上記では便宜上Javaのソースで『参照渡し』として、『ロッカーの鍵を渡す』と説明しましたが、これはです。
※多くの人が踏む勘違いのステップを踏んでもらうことで違いを分かり易くしようとした意図です。すいません。
※多くのJavaエンジニアが参照渡しだと思い込んで使っていることは事実です…


実際にはJavaでは参照型の変数を渡す場合、『参照の値渡し』が行われています。

参照の値渡しとは

『参照渡し』『ロッカーの鍵を渡す』ことだと例えるなら

『参照の値渡し』『ロッカーの鍵に書かれているロッカー番号を伝えること』と言えます。

では先程のソースを正しく説明し直しましょう


考える人考える人

ん~結局結果は一緒じゃろ?

じゃけぇじゃけぇ

このソースではそうだね。じゃあ次は参照渡しと参照の値渡しの違いが分かり易いコードを見せてあげよう

参照渡しと参照の値渡しで違いが起きる例

以下のソースを見て下さい


考える人考える人

おお!?ロッカーの中身が変わってないぞ??

じゃけぇじゃけぇ

ロッカーの鍵の現物が無いとロッカーを初期化しようとしても駅員さんが許可してくれない、とイメージすると良いよ。

えー鍵がないとダメなのか…
でもロッカー番号教えてもらっただけだしな…
でもnewしろってうるさいからな…



「そうだ!新しいロッカー申請すれば良いじゃん!」


と、Javaの参照の値渡しの場合こんなことが起こっているのです。

因みに本当の参照渡しの場合(C#で明示的にrefを付ける等)は、鍵があるので同じロッカーを初期化して使いまわすのでどちらの出力結果も


//ロッカーの中は[テスト用紙part2,カンペ]じゃ~!


と表示されます。ロッカーを無駄遣いしなくて良いですね~。

さいごに

私はこの話を知ったとき「おもしれー!!」と思ったのでなるべく初学者の人にも分かり易い形で説明してみました。

因みに、ここでのロッカーやロッカーの鍵番とか言ってるのがメモリやポインタだったりするわけですね。

あとここらへんの変数の書き換えの話に関しては、immutable(イミュータブル)mutable(ミュータブル)についても知っておかないといけないので興味のある人は調べてみてください。

気が向いたら記事にまとめようと思いますが…

私もまだまだぺーぺーなので何か間違いがあればご指摘頂けると幸いです。

それでは!また!!

最後まで読んで頂きありがとうございます!
人気の記事だけ集めたので是非覗いていってください^^
 厳選!目的別にオススメ記事を紹介-あなたの欲しい情報がここに-