Java
参照渡し
値渡し
評価戦略

Javaの「参照渡し」問題まとめ

More than 1 year has passed since last update.

概要

Javaの評価戦略は値渡しです。参照渡しではありません。
一部に、参照値を渡すこと指して「参照渡し」と誤用する人がいます。
それを誤用だと指摘する人、分かってて使ってるという人、本当に分かっていない人など色々いて、くすぶっているようですので、情報をまとめてみました。

評価戦略

計算機科学(computer science)には、評価戦略(evaluation strategy)という概念があります。
値渡し(call by value あるいは pass by value)も、参照渡し(call by reference あるいは pass by reference)も、その評価戦略の一種です。

詳しくは:
* Wikipedia: Evaluation strategy
* Wikipedia: 評価戦略

Javaの評価戦略

Javaの評価戦略は値渡しです。
Javaでいう参照値(reference values)・参照(references)を渡したときも、値渡しで評価されます。

そのことは、Javaの言語仕様にも書かれています。

When the method or constructor is invoked, the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor.

http://docs.oracle.com/javase/specs/jls/se9/html/jls-8.html#jls-8.4.1 より
私約:

メソッドかコンストラクタが呼び出されたとき、メソッドかコンストラクタのボディーの実行前に、実引数部表現ので、それぞれ宣言された型の新しい仮引数値を初期化する。

詳しくは、Scott Stanchfield が 書いたJava is Pass-by-Value, Dammit! を読んでください。

評価戦略についての正しい考え方

一般に評価戦略を考えるときは、関数やメソッドやサブルーチン等を呼び出しているプログラムをプログラミング言語処理系に入力したときに、その呼び出しがどのように評価されるかだけを考えるのが評価戦略の正しい考え方です。

プログラムやバイナリを実際に実行した時の挙動で考えてはいけません。プログラムの挙動は、プログラミング言語の実行環境によって全く変わってしまいます。例えば、プログラムの実行環境がコンパイラか、最適化はどこまでするか、インタープリタか、あるいは人間が黒板とチョークで「実行」するか、等で実際に行われる挙動は全くかわってしまいます。プログラミング言語の評価戦略を考えるときに、実際にCPUが何をするか、メモリはどうか、アドレスはどうか、等を考えてはいけません。

私見

Javaで参照を渡すことを「参照渡し」と呼ぶことについては即刻やめるべきです。 Java 参照渡し で検索してみれば分かりますが、あきらかに誤解した記事が見受けられます。 その何十倍か何百倍か、誤解したまま観測されていない人、誤用に引きずられて理解が妨げられている人がいるはずです。
こういうのをやめていかないと業界の損失になります。