作成日 : 2007/11/05 H.Naito
更新日 : 2007/11/14 H.Naito
勉強の成果!? ( メモ ) を残します。 by 内藤
この本の目的とするところ
- 基本的パターンの忠実な遵守
- 不必要な装飾を持たない
- 簡潔性と調和
ようするに、簡潔なコードを書いて、自分と他人にわかりやすく、メンテしやすいコードを書くための注意点を網羅したものだと予想しています。
# まだ全部読んでないので、断言できません。 ( 2007/11/05 現在 )
Java プログラマ教育のための教材として使われているようですね。
# 例えば、新人 Java プログラマに対して、この本読んで自分のコードを修正しろ!! みたいな・・・
第1章 : はじめに
第2章 : オブジェクトの生成と消滅
項目1 : コンストラクタの代わりに static ファクトリーメソッドの提供を検討する
項目2 : private のコンストラクタでシングルトン特性を強制する
項目3 : private のコンストラクタでインスタンス化不可能を強制する
項目4 : 重複したオブジェクトを生成するのを避ける
項目5 : 廃れたオブジェクト参照を取り除く
項目6 : ファイナライザを避ける
第3章 : すべてのオブジェクトに共通するメソッド
項目7 : equals をオーバーライドする時は一般契約に従う
項目8 : equals をオーバーライドする時は、常に hashCode をオーバーライドする
項目9 : toString を常にオーバーライドする
項目10 : clone を注意してオーバーライドする
項目11 : Comparable を実装することを検討する
第4章 : クラスとインタフェース
項目12 : クラスとメンバーへのアクセス可能性を最小限にする
項目13 : 不変性を選ぶ
項目14 : 継承よりコンポジションを選ぶ
項目15 : 継承のために設計および文章化する、でなければ継承を禁止する
項目16 : 抽象クラスよりインタフェースを選ぶ
- Java は複数の実装を許す型を定義するためにインタフェースと抽象クラスを提供している
- インタフェース
- 抽象クラス
- メソッドに対する実装を含むことが許されている
- 実装するクラスは、抽象クラスのサブクラスでなくてはならない
- 一般に、既存のクラスに対して抽象クラスを設定することはできない
- 2つのクラスに同じ抽象クラスを継承させたければ、それぞれのクラスの祖先になるように抽象クラスを継承させる必要がある
- インタフェースは、階層を持たない型フレームワークを構築することを可能にしている
- 発展のしやすさが、柔軟性と能力よりも重量だと考えられる場合には、抽象クラスを使用する
項目17 : 型を定義するためだけにインタフェースを使用する
項目18 : 非 static のメンバークラスより static のメンバークラスを選ぶ
第5章 : C 構文に対する置き換え
項目19 : 構造体をクラスで置き換える
項目20 : 共用体クラス階層で置き換える
項目21 : enum 構文をクラスで置き換える
項目22 : 関数ポインタをクラスとインタフェースで置き換える
第6章 : メソッド
項目23 : パラメータ正当性を検査する
項目24 : 必要な場合には、防御的にコピーする
項目25 : メソッドのシグニチャを注意深く設計する
項目26 : オーバーロードを注意して使用する
項目27 : null ではなく、長さゼロ配列を返す
項目28 : すべての公開API要素に対してドキュメントコメントを書く
第7章 : プログラミング一般
項目 29 : ローカル変数のスコープを最小限にする
- ローカル変数のスコープを最小限にする最も強力な技法は、ローカル変数が初めて使用されたときに宣言することです。
- ループ変数の内容がループした後に必要ない場合には、while ループより for ループを選んでください。
- ほとんどすべてのローカル変数宣言は、初期化子を含んでいるべきです。
→ 変数を合理的に初期化するのに十分な情報がなければ、情報が得られるまで宣言を先送りにするべきです。
項目 30 : ライブラリーを知り、ライブラリーを使う
- 標準ライブラリを使用することで、それを書いた専門家の知識と、それをあなたよりも前に使用した人々の経験を利用することになります。
- すべてのプログラマは、java.lang、java.util の内容とある程度 java.io の内容を知っているべきです。
項目 31 : 正確な答えが必要ならば、float と double を避ける
- ''float 型、double 型'' は、正確な答えを必要とする計算に使用しない ( 特に金銭計算 には適していない )
- float 型 と double 型は主に科学計算 と工学計算 のために設計され、2進浮動小数点算術を行う
- 2進浮動小数点算術は、広い範囲の大きさに対して正確な近似値 をすばやく行うために設計されている
- float 型、double 型を使用しないで計算する方法は 2つ
- BigDecimal を使用する
- int 型 もしくは long 型 を使用する
- [ 利点 ] 基本データ型なので高パフォーマンスを期待できる。
- [ 欠点 ] 9桁を超えたら int を使用できない。また、18桁を超えたら long を使用できない。18桁を超えたら BigDecimal を使用しなければならない。
項目32 : 他の型が適切な場合は、文字列を避ける
- 要するに、[はい/いいえ] なら boolean でもつとか、できる限り String 型で値を持ちましょうねという話らしいが、いまいち理解しきれない・・・
項目33 : 文字列結合のパフォーマンスに用心する
- 文字列の連結に文字列連結演算子(+) をできる限り使用しない
- 理由は、処理時間が遅いから。( n個の文字列を連結するのに、文字列結合演算子を繰り返し使用すると、nに関して2次の時間を必要とする )
- 文字列は不変の要素として扱われるので、結果的に、連結する要素のコピーを行うことになるというのが、そのからくり。
- 文字列連結する場合は、String の代わりに StringBuffer を使用し、append メソッドを使用する。
項目34 : インタフェースでオブジェクトを参照する
- インタフェースを使用してプログラムの柔軟性を高めなさいという話・・・だが、よく理解できない。
- [ Sample ] List subscribers = new Vector();
項目35 : リフレクションよりインタフェースを選ぶ
- java.lang.reflect に関する記述。reflection そのものがよくわからないので、後で勉強しなおす。
項目36 : ネイティブメソッドを注意して使用する
- ネイティブメソッドとは?
- C / C++ ( native programming language )などで書かれた特別なメソッド。Java Native Interface( JNI ) を使用して呼び出すことが可能。
- ネイティブメソッドの主な用途は?
- プラットフォーム固有の機構( レジストリ / ファイルロック )へのアクセスを提供する( → レジストリ操作は Java1.4 から提供されている )
- 古いデータへのアクセスを提供している古いコードのライブラリへのアクセスを提供する( → ものによっては、Java で書き換えた方が良い場合もある )
- パフォーマンスが重要な部分の処理を代行する( → Java1.3 以降は推奨していない )
- ネイティブメソッドを使用するデメリット
- ネイティブ言語は safe ではないので、メモリ破壊の影響を受ける場合がある。
- ネイティブ言語は、プラットフォーム依存なので、アプリケーションを自由にプラットフォーム間で移動できない。
- ネイティブ言語は、書くのが難しいし、読むのも難しい ( ← そうかなあ )
項目37 : 注意して最適化する
- 時期尚早の最適化は、良くなるよりは害になりやすい。
- 早いプログラムよりも、良いプログラムを書くように努めるべき。( 良いプログラムはカプセル化に成功しているので、変更点以外に影響を与えることない。 )
- 良いプログラムを書けば、結果としてスピードが得られる。
- 設計の段階からパフォーマンスを意識した構造を構築する。
- API、通信レベルのプロトコル、永続データ形式 などの設計要素を検討するときは、特に注意したい。
- 良い API 設計は、良いパフォーマンスと矛盾しない場合が一般的。
項目38 : 一般的に受け入れられている命名規約を守る
- Java プラットフォームには、確立した命名規約の集まりがあり、その多くは『Java言語仕様』に含まれている。
- パッケージ名の命名規則
- ピリオドで区切られた要素を持ち、階層的であるべき。
- 区切られた要素は、小文字のアルファベット文字と稀に数字から構成されるべき。
- 組織外で使用されるパッケージの名前は、トップレベルのドメインを最初にした、その組織のインターネットドメイン名で始まるべき。( ex. com.sun )
- java / javax で始まる標準ライブラリとオプションパッケージは、この規則に対する例外。( ユーザは java / javax で始まるパッケージを作成してはいけない )
- 詳細な規則については、『Java言語仕様』を参照のこと。
- パッケージ名の残りは、パッケージに記述する1つ以上の要素( 一般的に 8文字以下の1単語/1省略形 )から構成されるべき。
- 意味を持った省略形は推奨されている ( utilities → util、Abstract Window Toolkit → awt )
- クラス名 / インタフェース名の命名規則
- 1つ以上の大文字から始まる単語から構成されるべき( ex. TimerTask )
- 省略系は避ける ( 例外. 頭文字、min/max などの一般的な省略形 )
- インタフェース名は、-able や -ible で終わる形容詞で命名される。( ex.Runnable、Accessible )
- なんらかの処理を行うメソッドは、一般に動詞/動名詞で命名される。
- boolean 値を返すメソッドは、たいてい is で始まり、その後に形容詞/名詞(句) が続く。( ex. isDigit、isEmpty )
- メソッド名 / フィールド名の命名規則
- 基本は、クラス名 / インタフェース名と同じ規則。ただし、最初の文字は小文字から始める。頭文字の場合は、頭文字部分を全部小文字にする。
- 定数フィールドは、1つ以上の大文字から構成され、アンダースコアで区切られる。定数フィールドだけが、唯一アンダースコアの使用を推奨している。
- オブジェクト方を変換し、別の型の無関係なオブジェクトに返すメソッドは、たいてい toType と呼ばれる。 ( ex. toString、toArray )
- レシーバーオブジェクトの型と異なる型を持つビューを返すメソッドは、たいていは asType と呼ばれる。 ( ex. asList )
- メソッドが呼び出されたオブジェクトと同じ値を持つ基本データを返すメソッドは、たいてい typeValue と呼ばれる。 ( ex. intValue )
- static ファクトリーに対する共通の名前は、valueOf と getInstance 。
第8章 : 例外
項目39 : 例外的状態にだけ例外を使用する
項目40 : 回復可能な状態にはチェックされる例外を、プログラミングエラーには実行時例外を使用する
項目41 : チェックされる例外を不必要に使用するのを避ける
項目42 : 標準例外を使用する
項目43 : 抽象概念に適した例外をスローする
項目44 : 各メソッドがスローするすべての例外を文章化する
項目45 : 詳細メッセージにエラー記録情報を含める
項目46 : エラーアトミック性に努める
項目47 : 例外を無視しない
第9章 : スレッド
項目48 : 共有された可変データへのアクセスを同期する
項目49 : 過剰な同期は避ける
項目50 : ループの外で決して wait を呼び出さない
項目51 : スレッドスケジューラに依存しない
項目52 : スレッド安全性を文章化する
項目53 : スレッドグループを避ける
第10章 : シリアライズ
項目54 : Serializable を注意して実装する
項目55 : カスタムシリアライズ形式を使用することを検討する
項目56 : 防御的に readObject を書く
項目57 : 必要な時には readResolve メソッドを提供する
最終更新:2007年11月14日 14:24