Effective Javaを読むチャレンジ-項目10~11の1-

項目10 toStringを常にオーバーライドする

java.lang.ObjectのtoStringメソッドが「クラス名@ハッシュコードの符号なし16進数表記」というのは周知の事実。toStringは様々な処理で自動的に呼び出されるので、基本的にオーバーライドしてそのクラスを使うことに対する有益化を図りましょうということですね。toStringがオーバーライドされていないと、文字列化が必要になるたびにオブジェクトのデータを引っ張り出して文字列を組み立てないといけませんので、とても使いづらいです。XML処理など、こちらで手を加えられないAPIが自動でtoStringを呼び出しているのであれば、オーバーライドはなおさら必要ですね。

その場合はオブジェクトに含まれる興味がある情報をすべて返すべき、と筆者は言っています。また、Javaのマニュアルには、要約すると、「toStringメソッドの結果は人間が読める簡潔で有益な情報であるべき」とあります。この2点に注意してオーバーライドすればよいでしょう。

あと筆者の問題提起として、値クラスなどにおいて戻り値の形式をJavaDocに書くかどうか決めなくてはならないとあります。電話番号などを扱う場合、形式は重要です。もしJavaDocに細かにそれを書く場合、その形式に変更があった場合の影響は大きいですね。ほぼ永久的に変更できないことになります。じゃあ形式を書かなければいいのかというと、どう使えばいいか分からないものは誰も使いたがりません。もし形式を書きたくなければ、形式が変わるかもしれないけど大体こんな感じになるので・・・などとうまい口実を与えておくしかありません。ただ、普通は先々のことも考えて設計しますからね、きちんとJavaDocに記述するでしょう・・・。

項目11 cloneを注意してオーバーライドする

とにかく長くて訳の分からないcloneの項目。ひとつひとつ読んでいきましょうか。

Cloneableインターフェースはミックスイン・インターフェースとして意図されていたが、その目的を果たすのに失敗した

ミックスインというのは、そのクラス本来の機能とは別に、何らかの振る舞いを合わせ持つことを可能にすることです。ミックスイン・インターフェースは、その何らかの振る舞いを合わせて持たせるためのインターフェースです。たとえば、Comparableインターフェースは、そのクラスのオブジェクトに全体順序付けを強制します。つまり、そのクラスが本来持つ使い方とは別に、自然に比較できるようにもなるということを表します。

ComparableのcompareToメソッドなど、ミックスイン・インターフェースにはミックスインする何らかの振る舞いが定義されています。ですが、Cloneableインターフェースはcloneメソッドは持っていません。何の処理もないインターフェースです。そして、cloneメソッドはjava.lang.Objectクラスに定義されていて、しかもprotectedだということが主たる欠陥だと本書では言っています。

Cloneableインターフェースを実装していないクラスがcloneメソッドをオーバーライドしたとしても、そのcloneメソッド実行時に、java.lang.CloneNotSupportedExceptionがスローされます。強引にミックスインに見せかけるための仕掛けなんでしょうか。CloneableがJDK1.0からあるってことは後付けの苦肉の策ではなくて最初からこうだったのか・・・筆者が欠陥というのも頷けますね。

Cloneableを実装した結果の機構は言語外、つまり、コンストラクタを呼び出すことなくオブジェクトを生成する

Cloneableを実装するのは大変でドキュメントに書かれてない規約に多く従わないといけないようです。機構が言語外だというのはそういうことだと思いますが、その話の行き着く先が、コンストラクタを呼び出すことなくオブジェクトを生成することになる、というのがちょっと私には理解しきれていません。この後の長い説明を読む必要があります・・・。

ここまででまだ項目11の1ページ目終わってません。これは長くなりそうですね、次回に続きます。

広告
  • LINEで送る