少しずつまとめていきます。
Effective Java 3rd Edition
Effective Javaを理解するため、ChatGPTや原著の翻訳などを通して理解したものを載せていきます。(気分で更新するので遅いです)
この本の難しさとしては、個人的には以下の点を挙げたいと思います。
- API開発者としての視点とAPI利用者としての視点が混ざっている
- ここを押さえるとかなり読みやすくなので常に意識すること。
- 日本語訳がわかりにくい。
- 直訳という点はよいかもしれないが、読む際には回りくどい表現が多い。
- 結論が100%正しいわけではなく、状況に応じて臨機応変に対応することが求められている。
- 「Aの時はBが絶対だ」という読み方ではなく、「引き出しを増やす」という気持ちで読むべき。
これらを踏まえたうえで下記の文書を更新しています。
正誤表はこちら。(特に第1刷、第2刷を持っている人は要チェック)
章 | 項目 | タイトル | 備考 |
第1章 はじめに |
はじめに | ||
第2章 オブジェクトの生成と消滅 |
1 | コンストラクタの代わりにstaticファクトリメソッドを検討する | |
2 | 多くのコンストラクタパラメータに直面したときにはビルダーを検討する | ||
3 | privateのコンストラクタかenum型でシングルトン特性を強制する | ||
4 | privateのコンストラクタでインスタンス化不可能を強制する | ||
5 | 資源を直接結び付けるよりも依存性注入を選ぶ | ||
6 | 不必要なオブジェクトの生成を避ける | ||
7 | 使われなくなったオブジェクト参照を取り除く | ||
8 | ファイナライザとクリーナーを避ける | ||
9 | try-よりもtry-with-resourcesを選ぶ | ||
第3章 すべてのオブジェクトに共通のメソッド |
10 | equalsをオーバーライドするときは一般契約に従う | |
11 | equalsをオーバーライドするときは、常にhashCodeをオーバーライドする | ||
12 | toStringを常にオーバーライドする | ||
13 | cloneを注意してオーバーライドする | ||
14 | Comparableの実装を検討する | ||
第4章 クラスとインタフェース |
15 | クラスとメンバーへのアクセス可能性を最小限にする | |
16 | publicのクラスでは、publicのフィールドではなく、アクセッサ―メソッドを使う | ||
17 | 可変性を最小限にする | ||
18 | 継承よりもコンポジションを選ぶ | ||
19 | 継承のために設計および文書化する、でなければ継承を禁止する | ||
20 | 抽象クラスよりもインタフェースを選ぶ | ||
21 | 将来のためにインタフェースを設計する | ||
22 | 型を定義するためだけにインタフェースを使う | ||
23 | タグ付きクラスよりもクラス階層を選ぶ | ||
24 | 非staticのメンバークラスよりもstaticのクラスに限定する | ||
25 | ソースファイルを単一のトップレベルのクラスに限定する | ||
第5章 ジェネリックス |
26 | 原形を使わない | |
27 | 無検査警告を取り除く | ||
28 | 配列よりもリストを選ぶ | ||
29 | ジェネリック型を使う | ||
30 | ジェネリックメソッドを使う | ||
31 | APIの柔軟性向上のために境界ワイルドカードを使う | ||
32 | ジェネリックスと過変長引数を注意して組み合わせる | ||
33 | 型安全な異種コンテナを検討する | ||
第6章 enumとアノテーション |
34 | int定数の代わりにenumを使う | |
35 | 序数の代わりにインスタンスフィールドを使う | ||
36 | ビットフィールドの代わりにEnumSetを使う | ||
37 | 序数インデックスの代わりにEnumMapを使う | ||
38 | 拡張可能なenumをインタフェースで模倣する | ||
39 | 命名パターンよりもアノテーション選ぶ | ||
40 | 常にOverrideアノテーションを使う | ||
41 | 型を定義するためにマーカーインタフェースを使う | ||
第7章 ラムダとストリーム |
42 | 無名クラスよりもラムダを選ぶ | |
43 | ラムダよりもメソッド参照を選ぶ | ||
44 | 標準の関数型インタフェースを使う | ||
45 | ストリームを注意して使う | ||
46 | ストリームで副作用のない関数を選ぶ | ||
47 | 戻り値型としてStreamよりもCollectionを選ぶ | ||
48 | ストリームを並列化するときは注意を払う | ||
第8章 メソッド | 49 | パラメータの正当性を検査する | |
50 | 必要な場合、防御的にコピーする | ||
51 | メソッドのシグニチャを注意深く設計する | ||
52 | オーバーロードを注意して使う | ||
53 | 可変長引数を注意して使う | ||
54 | nullではなく、空コレクションか空配列を返す | ||
55 | オプショナルを注意して返す | ||
56 | すべて公開のAPI要素に対してドキュメントコメントを書く | ||
第9章 プログラミング一般 | 57 | ローカル変数のスコープを最小限にする | |
58 | 従来のforループよりもfor―eachループを選ぶ | ||
59 | ライブラリを知り、ライブラリを使う | ||
60 | 正確な答えが必要ならば、floatとdoubleを避ける | ||
61 | ボクシングされた基本データよりも基本データ型を選ぶ | ||
62 | 他の型が適切な場所では、文字列を避ける | ||
63 | 文字列結合のパフォーマンスに用心する | ||
64 | インタフェースでオブジェクトを参照する | ||
65 | リフレクションよりもインタフェースを選ぶ | ||
66 | ネイティブメソッドを注意して使う | ||
67 | 注意して最適化する | ||
68 | 一般的に受け入れられている命名規約を守る | ||
第10章 例外 |
69 | 例外的状況にだけ例外を使う | |
70 | 回復可能な状態にはチェックされる例外を、プログラミングエラーには実行時例外を使う | ||
71 | チェックされる例外を不必要に使うのを避ける | ||
72 | 標準的な例外を使う | ||
73 | 抽象概念に適した例外をスローする | ||
74 | 各メソッドがスローするすべての例外を文書化する | ||
75 | 詳細メッセージにエラー記録情報を含める | ||
76 | エラーアトミック性に努める | ||
77 | 例外を無視しない | ||
第11章 並行性 |
78 | 共有された可変データへのアクセスを同期する | |
79 | 過剰な同期は避ける | ||
80 | スレッドよりもエグゼキュータ、タスク、ストリームを選ぶ | ||
81 | waitとnotifyよりも並行処理ユーティリティを選ぶ | ||
82 | スレッド安全性を文書化する | ||
83 | 遅延初期化を注意して使う | ||
84 | スレッドスケジューラに依存しない | ||
第12章 シリアライズ |
85 | Javaのシリアライズよりも代替手段を選ぶ | |
86 | Serializableを細心の注意を払って実装する | ||
87 | カスタムシリアライズ形式の使用を検討する | ||
88 | 防御的にreadObjectメソッドを書く | ||
89 | インスタンス制御に対しては、readResolveよりもenum型を選ぶ | ||
90 | シリアライズされたインスタンスの代わりに、シリアライズ・プロキシを検討する | ||
初級
セクション | キーワード |
開発と実行の流れ | コンパイル。コンパイラ。インタプリタ。クラスファイル。CPU。JVM。マシン語。 |
Javaプログラムの基本構造 | ブロック。クラスブロック。メソッドブロック。クラス名。インデント。コメント。mainメソッド。 |
変数 | 変数。メモリ。識別子。予約語。データ型。型。初期化。定数。 |