半端である

うちの新人にJavaプログラミングを教えているのだが、文系女子であるせいか、なかなかプログラミングのコツを掴んでくれない。そのため、とにかく掘り下げて、懇切丁寧に教えなければならないのだが、その過程で痛感したことがある。Javaって、半端な言語だよねぇ。

・・・今更か。

文字列の長さを取りたいとする。このとき、手続き型言語であるCであれば、次のように書く。

int len = strlen(str);

データと手続きが分離しているので、文字列の情報を外から調べて取得しなければならない。

これに対して、オブジェクト指向言語であるところのJavaでは、文字列もオブジェクトであり、自分自身の情報と、他のオブジェクトとの会話手段を持っている。よって、長さを知りたければ、わざわざ外から調べてやる必要はない。ただ、そいつに聞けばよいのだ。人の名前を知りたければ、直接その人に聞くのが一番手っ取り早いのと同じだ。

int len = str.length();

俺はおおむねこのように説明している。オブジェクトに対して作業を依頼する、ということを繰り返して処理が進むのだ、と。

ところで、簡単な課題としてファイルの中身を並び替えて表示させるプログラムを書かせ、その説明をした。ファイル中の全ての行を配列(実際に使ったのはListだけど)に取り込み、並び替え、表示するだけである。Javaでは、配列の並び替えをしたい場合、次のように書く。

array.sort();

嘘である。Javaの配列はメソッドなど持っていない。正しくは、java.util.Arraysを使って、次のように書く。

Arrays.sort(array);

困る。これはC言語と同じやり方じゃないか。「オブジェクトに対して作業を依頼する」という説明と矛盾してしまう。先に書いた間違ったコードのほうが、オブジェクト指向言語としては筋が通っている。

同じ処理を、Rubyでは次のように書く。

array.sort!

エレガントだ!これがオブジェクト指向言語ってもんだろう。RubyはEiffelやSmalltalkのようにほとんど全ての値がオブジェクトとして扱われるので、こういうまねができる。

Javaはパフォーマンス維持のために、よく使われる整数値などはプリミティブ型にしてしまったわけだが、これは失敗だったかもね。プリミティブ型の変数を扱う場面ではオブジェクト指向的な記述が崩れてしまう。そのため、突き詰めるほどに一貫性が無くて覚えづらく、扱いづらいという印象が深まる。

これ以外にもいろいろある。配列の長さを取る方法はarray.lengthなのに、なんでjava.util.Collectionはsize()なのか、そして文字列の長さはlength()って、何をふざけているのか、とか。java.util.Stackはスタックを名乗るくせに好きな位置にデータをつっこめるのはどーなのよ、とか。

それでも、複雑極まるC++なんかに比べればずっと扱いやすい言語だし、飯の種でもあるので技術動向は追い続けるわけだが、オブジェクト指向という概念を掴みたいと思う人は、あまりJavaから入るのはオススメできないなぁ、と思う。Rubyから入りたまえよ、うん。