はじめに
一歩進んだJavaの理解とはどういうことでしょう?
それは、自分で書いたプログラムコードについて、「なぜインターフェース型を使うのか、なぜこのデザインパターンを使うのか、なぜこの実装クラスをコレクション型として選択したのか、なぜエラー処理に例外を使ったのか、なぜジェネリック型を定義したのか…」、など自分の書いたコードの意図を他人に説明できるようになっなったときではないでしょうか?
中には、イディオム(慣習)だからこう書く、あるいはパターンだからこう書く、という理由の時もあります。イディオムやパターンも立派な理由です。イディオムやパターンだからという理由を自信を持って伝えるには、さまざまなことを知る必要があります。
今回はその中で、参照に関して簡単に説明します。
Javaプログラミングの理解の基礎
Javaプログラミングの理解の基盤に、オブジェクトへの参照の理解があります。この概念を理解できれば、Javaの多くのソースコードを読んで理解できるようになります。
「オブジェクトとはどこかに存在するもの」
「オブジェクト」はそれ自体は本質的に名前がありません。これは、プログラミング言語の文脈でオブジェクトという用語を使った時の原則です。
しかし、オブジェクトを名前で呼べないと不便です。そこで、いくつかの例外を除いて、Javaプログラミングではオブジェクトに名前をつけます。
ではどのように名前をつけるのでしょうか?
「変数とはオブジェクトを名前で呼ぶ橋渡し」
名なしのオブジェクトに名前をつけて呼ぶための橋渡しをするのが「変数」です。
変数は変数名という形で、それ自体が名前としての役割を担います。変数とオブジェクトを結びつけて、(名前を持った)変数を通じて、(名なしの)オブジェクトにたどりつく、この概念こそが参照型変数を説明するモデルです。
このモデルを図Aに示します。
図A オブジェクトに変数の名前でアクセス
説明が抽象的と感じる人のために説明を少し具体化します。
オブジェクトは名なしですが、どこかに存在する以上、存在する場所があります。専門的に言うと、オブジェクトの場所を示す位置情報(アドレス)があります。
後述しますが「参照」とは、この位置情報を指し示すことだと理解しても構いません。これを「オブジェクトの参照」もしくは「オブジェクトへの参照」という用語を使います。「変数がオブジェクトの参照を持つ」や「変数がオブジェクトを参照する」という言い方もします。これは、変数にオブジェクトの位置情報を結びつけて、変数(名)を使ってオブジェクトに辿り着く手段ができることを意味します。
「参照とはオブジェクトの位置情報を指し示す何か」
変数の箱モデルから抜け出せない人は、「変数の箱にオブジェクトの位置情報を入れること」を理解をしてください。C言語などの経験者であれば、この理解がそのままポインタ型変数の説明になっていることに気づくでしょう。Javaの参照型変数をポインタ型変数に読み替えて理解しても問題はありません。本質的には同じだからです。ただし、いくつかの違いがあります。
- C言語のポインタ型変数の値がメモリ上のアドレス値そのものであるのに対し、Javaの参照型変数の値はそうではない点
- C言語のポインタ型変数は、その値に対する演算ができるの対し、Javaの参照型変数の値は演算ができない点
これがポインタ型変数と参照型変数の決定的な違いです。参照型変数の持つ値は、「オブジェクトの位置情報を指し示す(値を意識しない抽象的な)何か」と考えるべきです。この「何か」こそが「参照」です。
最後に 自分の書いたコードを説明できる意義
書いたコードの意図を説明できることは、プログラミングに絶対の正解があり、一つの原則ですべてを説明可能という意味ではありません。書いたコードに関する考え方の一つを示せる、という意味です。
しかし、考え方を提示してコードの意図を説明できるようになると、プログラムコードで議論ができます。これにはコードの品質が上がるという実利以上の意味があります。
また、他人に意図を説明できるコードを書けるようになると、コードを書くことが楽しくなるのです。明瞭な意図を持って書くプログラミングは、ぼんやりした理解で書く作業よりもずっと楽しいものです。
それでは、皆さんもプログラミングがわかる楽しさに目覚めてください!