この国では犬が

本と芝居とソフトウェア

プログラミング言語Java 第1章 はやめぐり

気を取り直して、プログラミング言語Javaを読む。

 

基本的にC++の経験をベースに読んで、気になったとことか気づいたことをつまんで記録していく感じにしようと思っている。

 

1.1 さあはじめよう

クラス、インスタンス、オブジェクト、メンバといった用語についてはC++と差がなさそうだ。フィールド、メソッドという用語が独特だが、それぞれメンバ変数とメンバ関数のことであると解すればわけない。

 

しかし、初っぱなクラスとインスタンスの説明で、「機械の設計図および工場と機械」のたとえが持ち出される。昔からこの喩えがいまいちピンと来ない。概念と実体とか、抽象と具体とか、形相と質料とか、まあどれも本当に正確ではないかもしれないけど、その方がまだ実質に近いと思うのだけど。

が、結局どれも正確でないとしたら、一つだけ例を挙げるには、一番多くの人に伝わりそうな例を挙げておくのが無難だ。とすると、「設計図および工場とプロダクト」のたとえに落ち着くのだろう。なんか納得。 *1

 
1.2 変数

JavaのcharはUTF-16 。でかい!

でかい!しか感想がないので文字コードについて早急に学ぶ必要を感じる。UTF-8でないのは歴史的な経緯とかがあるのだろうか。

 

あとラッパークラス、toString、Rubyでいうところのto_sが使えたりするのがウリなのであろうと推測するが、では逆にプリミティブ型が存在する意義は何だ、とも問いたくなる。速度?むしろ歴史的な経緯の匂いがする。(もちろんそれだけではないのだろうけど)

 

C++を嗜んでいると歴史的な経緯に敏感になる……のかもしれない。(なんでもかんでも歴史的な経緯だと言っているだけともいえる)

 

1.3 コード中のコメント

/*

複数行コメント

*/、

// 行コメント、

/** ドキュメンテーションコメント */。

 

ドキュメンテーションコメント!

 

これらのドキュメンテーションコメントは、作成したクラスのリファレンスドキュメントを生成するためのツールにより取り出すことができます。

 

かっこいい。本当にかっこいいかは使ってみないとわからないが、言語組み込みでそういうのがあるところがJavaの国に来たなって感じがする。

 

1.4 名前付き定数

enumが出てくる。C++enumは少々中途半端なところがあるのでJavaenumに期待が高まるが、詳細は第6章までおあずけ。

 

1.5 Unicode文字

出た。

けど、「変数名にπを使用できます」とは書いてあっても「πを使用すべきです」とは書かれていない。

安心した。

 

1.6 制御の流れ

for、if-else、switch、do-whileがあるのはC++と同じ。

C++みたいに前置インクリメントと後置インクリメントでコピーの回数が異なる……なんてことがあるのか気になったけど、もちろんそんなことまでは書かれていない。(まああるかないかでいったらあると思うけど、気にするようなものなのか不明)

 

1.7 クラスとオブジェクト

すべてのオブジェクトはオブジェクト参照(object reference) を通してアクセスされます。

まじか。

そういえば、Rubyもそうだったかしら。(うろおぼえ)

 

1.8 メソッドとパラメータ

パラメータ名x、フィールド名xでthis.xとして参照する話など。

名前の隠蔽見るとうってなるけど、Javaの世界ではありなのかしら……。

ていうか、普段見通しのよくないコードばっか読んでるからうってなるだけかもしれない。関数が一画面に収まっていれば、それがローカル変数なのか、パラメータなのか、フィールドなのかはすぐにわかる。(と、『実装パターン』には書いてあった)

 

1.9 配列

配列はまあ、何のことはない配列。

でも配列も単なるポインタではなく一種の型であるらしい。lengthフィールドとかいるし。今までのところすんなり理解できてきたけど、配列が型というのは謎が残って嫌な感じがする。

条件論理式の遅延評価はC++と同じ。

 

1.10 文字列オブジェクト

Stringオブジェクトは、読み出しのみ可能(read-only) であり、不変(immutable) です。

まじか。

C++的感覚から考えたら、すげー効率悪いのでは……?

と思ったら、そんな我々のためにStringBuilderとStringBufferというクラスがあるらしい。詳細は不明だが、いかにもJavaっぽいソリューションの匂いがする。ワクワクしてきた。

 

それからちょっとだけ、==はオブジェクトの同一性をテストし、equalsメソッドはオブジェクトの同値性をテストする話。正直どっちがどっちか忘れてた。そういえばJavaには演算子オーバーロードってあるのだろうか……。

 

あとは、printf文の書式指定子として%nってのが出てきた。\nではプラットフォーム依存になってしまう由。(というか、LF決め打ちになる?)何にせよ、しばらく慣れそうにない。

 

1.11 クラスを拡張する

すべてのクラスはObjectクラスを暗黙的に拡張している。

 

キャスト。

name = (String)obj; // これでよし

これでよし。こういうキャストを見ると邪悪なCスタイルキャストを思い起こすが、Javaはどうもちょっと違うらしい。キャストがデフォルトでdynamic_castみたいなものなのかな。でもできるだけコンパイル時に教えてほしいと思うけど、

賢いコンパイラーであれば、コンパイル時に正しいかを判断するかもしれません。

なんかちょっと頼りない。

 

1.12 インタフェース

出たぞ、インタフェース。

今のところC++でいう「純粋仮想関数しか持たない仮想クラス」との違いが不明。「純粋仮想関数しか持てない仮想クラス」?あとは、たしかJavaは多重継承ができないので、そこのオルタナティブという意味もあったか。それから拡張時にextendsという専用の予約語を使うあたりも辛うじて違うけど、その意味も今のところ不明。いや、これだけ出揃ってれば存在する理由としては十分なのかも。

 

1.13 ジェネリック

テンプレートがあるのがC++のいいところだと信じていたけど、Javaにもあるじゃん。

ジェネリック型。TMPとかやりはじめると微妙な違いが大きな違いになってくるのだろうけど、ここに出てきてるだけでも既に十分ジェネリックだと思う。ワイルドカードとか、C++にはないし。

そんなことすら知らなかったくらいJavaを知らない。思い返してみれば、例がJavaで書かれた本でよくわからんと感じていた部分はだいたいジェネリック型が使われていたように思う。

 

1.14 例外

出た、チェック例外。

C++を始めたころは好き勝手発生しまくる例外に、これがあればどんなに楽かと思った。例外指定に夢を見て、unexpected()に裏切られて泣(く前に、Herb Sutter先生に助けていただ)いたこともあった。が。別に全部チェックされるわけでもないのですね。まあ実行時例外はそりゃそうかなとして、それ以外も、指定しないとチェックされるとは限らない?風な書き方。(誤解があるかもしれません)

これはこれで、使い方が難しそう……。

 

あとfinallyってのもあるけど、C++のRAIIに慣れ親しんだ身からすると、半信半疑といったところ。まあ、便利には違いない。

 

1.15 アノテーション

Javaっぽい組み込みドキュメンテーション機能第二弾。

でもレビュー履歴はコードに書かないで外部で管理したほうがいいと思う。いや、運用次第かもしれないけど……。

 

1.16 パッケージ

これも理屈はわかるんだけど、どう使ったらうまくいくかは、現実のプロジェクトでの使い方を見てみないと(それから使ってみないと)わからないなという感想。

 

1.17 Javaプラットフォーム

理想が語られている。

まあ、プリミティブ型のサイズが決まっているのはとにかく楽でよい。

現実を知っておく必要を感じる。

 

1.18 その他の機能について

Javaは組み込みでスレッドのサポートがあるのもよい。

リフレクションは、RTTIとしても知られているとか書いてあるけど、C++のRTTIならdynamic_castのときに使われることくらいしか知らないし、これだけじゃ何のことやらわからない。とにかくダイナミックであることはわかる。16章までおあずけ。

 

こうして見るとなかなか楽しそうな言語だ。

やはり何よりユーザがたくさんいて、周辺ツールもたいへん充実しているあたり、夢が広がる。

 

本のまとめやる(やりながら好き勝手なこと書く)のって結構楽しいかもしれない。

でもちょっと垂れ流しすぎな感じがするし、いつか読み返したときに顔から火を吹くことは間違いないので、無知を垂れ流しすぎずにもう少し聡明な感じで要点をかいつまみながら進めたいと思っています。(すごく難しそうだ……)

*1:と、はじめは思ったのだけど、Rubyとかクラスもオブジェクトだったりするし、Javaだってクラスにもstaticフィールドとかで実体があったりするし、全然ダメだ!工場と機械のほうがまだ潔くていい。すみませんでした。