第1条には設定された静的なファクトリメソッドに置き換えられ
「静的メソッド」に置き換え静的ファクトリメソッドは、より良く理解されている異なる静的工場における静的工場、及びデザインパターンは、主推薦は、オブジェクトを作成する静的メソッドを記述することです。
静的メソッドの利点を使用します。
1は、静的メソッドは名前を持っている、あなたはまさにそのようなリターンの、どのようなタイプなどのパラメータに応じて、機能を記述することができます。
図2は、その後、必要なオブジェクトを作成するメソッドを呼び出して、オブジェクトのインスタンスを作成する必要はありません。静的メソッドの使用がコールする静的メソッド名のクラス名から直接使用することができます。
図3は、任意のサブタイプのオブジェクトのオリジナルタイプに戻ることができます。
図4に示すように、異なる得るために、異なるパラメータ、戻り値を通過します。
図5は、クラスメソッドは、オブジェクトが属する返し、そのようなJDBCのAPIなどの静的メソッドを含むクラスの調製に存在しなくてもよいです。
6、オーバーヘッド場合静的メソッドを使用してとは対照的に、コンストラクタメソッドを使用してオブジェクトを作成し、新たなブール(文字列)とBoolean.valueOf(Stirng)として、はるかに大きいです。
欠点や不備
図1は、静的メソッドでオブジェクトを返すために、それはアクセス可能でなければならないオブジェクトクラスのコンストラクタに属し、またはインスタンス化することができません。
2、より困難な静的メソッドが発見されます。
第2条には、ビルダーは複数のコンストラクタに遭遇考えます
クラスのコンストラクタまたはstaticファクトリとき、あなたはより多くのパラメータを持っているとき、または後者のパラメータは、設計部門では、増加させることができるとき、あなたはビルダーパターンを使用することができます。
パッケージcn.ganlixin.effective_java。 パブリッククラスBuilderTest { パブリック静的無効メイン(文字列[] args){ 最終的な人の人=新しいPerson.Builder()ID(1).nameの( "ganlixin")(ビルド)。 } } クラス人{ プライベートint型のID。 プライベート文字列名; 個人(ビルダービルダー){ ID = builder.id。 名前= builder.name。 } パブリック静的クラスビルダー{ //ビルダ一般来说包含有外层类相同的属性 プライベートint型のID。 プライベート文字列名; 公共ビルダーID(int型のval){this.id =ヴァル。これを返します。} パブリックビルダー名(文字列ヴァル){this.name =ヴァル。これを返します。} 公共の人物ビルド(){(この)新しい人を返します。} } }
上記のコード、ロンボクの使用、そしてだけに@Builderのコメントを使用する必要があります。
パッケージcn.ganlixin.effective_java。 輸入lombok.Builder。 パブリッククラスLombokBuilder { パブリック静的無効メイン(文字列[] args){ 最終的な人の人=新しいPerson.PersonBuilder()ID(1).nameの( "ganlixin")(ビルド)。 } } @Builder クラス人{ プライベートint型のID。 プライベート文字列名; }
列挙型またはプライベートコンストラクタとシングルトン補強性:第3条
シングルトン:
1、コンストラクタの民営化を通じて、新しいキーワードを使用してオブジェクトを作成するために、クライアントを防ぐために、
図2に示すように、シングルトンオブジェクトを取得する静的メソッドが提供されます。
上記の二つの問題は、作成され、例外がスローされた場合、かどうかを決定するのインスタンスを作成するように構成することができる反射によってAccessibleObject.setAccessible()コンストラクタメソッド呼び出しを使用することができます。
3、質問シングルトンオブジェクトの配列;
例では、すべての列挙、次の例の単一の属性を作成します。
パブリッククラスSingletonEnum { パブリック静的無効メイン(文字列[] args){ 最終OneDemoインスタンス= OneDemo.INSTANCE。 instance.test(); } } 列挙OneDemo { INSTANCE。 //定义其他機能 公共ボイド試験(){ // ......... } }
第4条:強化能力は、プライベートコンストラクタでインスタンス化することはできません
我々はツールを作成するときのツールがインスタンス化されるのを避けるために、抽象クラスとして宣言することはできるが、一般的なツールでは、インスタンス化されるべきではなく、抽象クラスのサブクラスをインスタンス化することができるので、これは、良いではありません!
解決策:コンストラクタのパラメータを使用すると、例外をスローすることができているツールの声明を示しませんでした。
MyUtil {クラス プライベートMyUtil(){RuntimeExceptionをスロー新しい(「ツールがインスタンス化すべきではない」)新しい;} メソッド//宣言ツールクラス のパブリック静的な無効MyMethodは(){} }
第5条:参照リソースの依存性注入を優先
主に依存性注入の話。
問題はこれです:メールを受信するために、あなたは、あなたが次のコードを記述します(ホワイトリストに一致する)、再び濾過する必要がある、メールのホワイトリストがあります:
//メールフィルタ クラスmailchecker { //ホワイトリスト、死んで書かれたコード のプライベートリスト<文字列> =新しい新しいホワイトリストのArrayList <文字列>(){{ 追加(「123」);追加(「456」);追加( "789"); }}; //検査動作 パブリックブールのisValid(メールの文字列){ (メールで)リターンwhiteList.contains; } }
上記のコードはので、良いではありません。
1、フィルタリストは死んで書くこと。
2、唯一のフィルタリングを郵送し、それは疑問を持っているかもしれない、あなたが特定の機能しませんか?これは問題ありませんが、「携帯電話のフィルタ」がある場合PhoneCheckerそれを持ってするつもりはありませんか?
お勧め:ホワイトリスト外からインポートフィルタ死んホワイトリストに書いていないが、フィルタ機能は、次のように読んで、唯一フィルタリングすることです。
UseInject公共{クラス のpublic static無効メイン(文字列[] args){ //はPhoneListとしては、外部通過、またはファイルが読み取られると仮定する 。一覧の<string> PhoneListとして= NULLを チェッカーphoneChecker =新しい新しいチェッカー(PhoneListとして); phoneChecker .isValid( "123"); } } クラスチェッカー{ プライベートリストの<string>ホワイトリスト; //外部着信ホワイトリスト(...電話、電子メール、アドレスであってもよい)を受ける 公共チェッカー(リストの<string>ホワイトリストを){ this.whiteList =ホワイトリスト; } //チェック動作 パブリックブールのisValid(文字列ヴァル){ 戻りwhiteList.contains(ヴァル); } }
次のような、依存関係を使用してSpringフレームワーク、直接注入を使用している場合:
パブリッククラスUseInject { @value( "$ {PhoneListとして}") プライベート静的リスト<文字列> PhoneListとして; パブリック静的無効メイン(文字列[] args){ チェッカーphoneChecker =新しいチェッカー(PhoneListとして)。 phoneChecker.isValid( "123")。 } }
第6条:不要なオブジェクトを作成しません
1、Javaの自動包装及び自動包装は、しかし、基本データ型を使用しようとするものの、
図2は、クラスの静的ファクトリメソッドやコンストラクタを提供するために、優先順位ではなく、コンストラクタの静的メソッドを使用してオブジェクトを作成するためにであるべきです。
図3に示すように、いくつかのオブジェクトがあり、そのような正規表現のようなパターンのインスタンスを作成するために繰り返されてはなりません。
データベース接続を確立するためのコストは、比較的大きい共通目標価格を作成することが比較的小さいため、図4に示すように、独自のオブジェクトプーリングを除き、データベース接続プールを維持するために避けるべきです。
5.より多く支払うことになる、不要なオブジェクトを作成しないようにするために、いくつかのケースでは硬すぎてはいけません。
第7条:オブジェクトが古い参照を排除
1は、クラスがメモリを管理することであるならば、あなたはメモリリークを防ぐために必要がある必要があります、任意のオブジェクト要素が一度解放適用され、含まれる要素を空にする必要があります。
2キャッシュはメモリリークが発生、あなたはのWeakHashMap使用することができます。
サービスは、クライアントの呼び出しに提供されている場合、図3に示すように、クライアントが繰り返しオブジェクトを生成するかどうかに警告するのコールを繰り返したが、ゴミをクリーンアップしませんでした。
第8条:方法と除去方法の終了を使用しないでください
オブジェクトの先頭が到達不能になったから1は、方法(ファイナライザ)の終わりと除去方法(クリーナー)はタイムリーな実装がされる保証することはできません、これらの2つの方法のいずれかを実行するためのイベントが長いので、作業時間に注意を払っていませんそれはファイナライザとクリーナーで完了する必要があります。
2は、これら2つの方法が実行される機会を持っていない可能性があるため、永続的な状態は、重要である更新するファイナライザとクリーナー方法を頼るべきではありません。
図3は、にSystem.gcとSystem.runFuinalizationはファイナライザを向上させ、クリーンな機会を実行し、注意を払って、可能性を増大させるではなく、保証、100%;
4は、異常なファイナライザが登場し、プロセスの終わりには、死にたい、不気味な終了も死ぬわけにはいかないであろう。
5、プログラムのパフォーマンスが低下するため、ファイナライザ攻撃。
第9条:トライしてリソースのtry-最終的に優先します
try-とリソースを使用するには、AutoCloseableクラスがインタフェースを(ほとんどのクラスが実装)を実装する必要があります。
本の中で例の以下の例:
()IOExceptionがスロー公共{notSuggest静的な無効 BufferedReaderのBufferedReaderの= nullを 試し{ ()FileReaderの新新( "demo.txt")BufferedReaderの新しい新=をBufferedReader; はBufferedReader.readLine(); } {最後に bufferedReader.close(); } //上記demo.txtが存在しない場合、異常にFileNotFoundExceptionを報告し、最終的にエラーが近いことが、例外を閉じますのreadLine例外をカバーすることに注意してください 。//そうnotSuggest()メソッドは、唯一の例外例外近いが表示されます呼び出します「メイン」のjava.lang.NullPointerExceptionでスレッド }
以下に、あなたはすべての例外をキャッチすることができますが、良いコードが肥大化しているように見えますように。
公共notSuggest2静的な無効(){ BufferedReaderのBufferedReaderの= NULL; {試し ()FileReaderの新新( "demo.txt")BufferedReaderの新しい新=をBufferedReader; はBufferedReader.readLine(); }キャッチ(FileNotFoundExceptionをE){ e.printStackTrace(); }キャッチ(IOExceptionをE){ e.printStackTrace(); } {最後に 試し{ bufferedReader.close(); }キャッチ(IOExceptionをE){ e.printStackTrace(); } } //すべての異常情報(にFileNotFoundExceptionをプリントアウトがそして、NullPointerExceptionが近い例外) //常識、前の手順が間違っていた場合には、もはやに行くべきではありませんが、FileNotFoundExceptionをした後、近くに最終的に実行されます、結果は異常があらわれました }
推奨のtry-とリソース
提案する静的な無効パブリック(){ 試み(BufferedReaderのBufferedReaderのBufferedReaderの新しい新=(FileReaderの新新( "demo.txt"))){ はBufferedReader.readLine(); }キャッチ(例外E){ e.printStackTrace(); } //ませんそれぞれの子は、FileNotFoundExceptionを、IOExceptionを等の異常をキャッチする必要があるかへの直接書き込み例外 demo.txt上に//が存在しないので、java.io.FileNotFoundExceptionがあるでしょうが、ああ、2番目の例外が報告されていません }