Effective Java読書ノート(1)

4911 ワード

オブジェクトの作成と破棄
第一条:コンストラクタの代わりに静的工場法を考慮する
クラスが異なるインスタンス(サブクラスインスタンス)を返す必要がある場合、または唯一のインスタンス(単一のインスタンス)を返す必要がある場合は、コンストラクタの代わりに静的ファクトリメソッドを使用することを考慮します.静的ファクトリメソッドのいくつかの慣用名:
  • valueOfが返すインスタンスは、パラメータと同じ値であり、タイプ変換
  • に相当する.
  • of valueOfの簡略化
  • getInstanceが返す例はパラメータクラスによって記述されるが、一般にパラメータと同じ値は持たない.Singletonの場合、パラメータはなく、唯一のインスタンスを返します.
  • newInstanceはgetInstanceと似ていますが、新しいインスタンス
  • が戻るたびに
  • getTypeは、ファクトリメソッドが異なるクラスにある場合に使用され、Typeは戻りタイプのタイプ
  • を指す.
  • newType同上
  • 第二条:複数のコンストラクタパラメータに遭遇した場合、コンストラクタの使用を考慮する
    作成オブジェクトが複数のオプションパラメータに直面する場合(コンストラクタに複数のオプションパラメータがある場合)、次の3つのシナリオがあります.
  • オーバーラップコンストラクタモードは、パラメータの異なる組合せに基づいて、複数の署名の異なるコンストラクタまたは静的ファクトリメソッドを記述する.利点:スレッドは安全で、パラメータの組み合わせが少ない場合は簡単です.欠点:パラメータの数が多く、その組み合わせが多い場合、コードの作成が面倒で、可読性が悪い
  • .
  • JavaBeanモードでは、コンストラクタクラスを呼び出してオブジェクトを作成し、必要なパラメータを設定し、setterメソッドクラスで各オプションパラメータを設定します.利点:インスタンスが簡単で、コードが簡潔で、拡張性が強い.欠点:構築プロセスは複数の呼び出し方法に分けられ、一貫性を保証することが難しく、エラーが発生しやすくデバッグが困難である;可変オブジェクトをインスタンス化できない(致命的)
  • Builderモードでは、目的のオブジェクトを直接生成するのではなく、必要なパラメータでbuilderをインスタンス化し、setterメソッドで各オプションパラメータを設定し、最後にパラメータのないbuildメソッドを呼び出して可変のオブジェクトを生成します.オーバーラップコンストラクタモードのセキュリティを保証するとともに、JavaBeanのように簡単に読める
  • を保証することができます.
    第三条:プライベートコンストラクタまたは列挙タイプでSingleton属性を強化する
    Singletonを実現するには、次の3つの方法があります.
  • コンストラクタをプライベート化し、インスタンスをパブリック静的finalメンバーに設定します.プライベートコンストラクタは、単一のインスタンスをインスタンス化するために1回のみ呼び出されます:
  • public class FirstSingleton {
        public String message;
        public static final FirstSingleton INSTANCE = new FirstSingleton();
    
        private FirstSingleton(){
            message = "Hello World! First Singleton!";
        }
    }
    

    公有または保護されたコンストラクタが欠けているため、単一の例のグローバル一意性が保証される.
    注意:特権を有するクライアントはAccessibleObjectを利用することができる.setAccessibeメソッドは,反射機構によりプライベートコンストラクタを呼び出す.このような攻撃を防ぐ必要がある場合は、プライベートコンストラクタを変更して、2番目のインスタンスを構築するときに例外を放出することができます.
  • 共有メンバーは静的ファクトリメソッドです:
  • public class SecondSingleton {
        public String message;
        private static final SecondSingleton INSTANCE  = new SecondSingleton();
        private SecondSingleton(){
            message = "Hello World! Second Singleton!";
        }
        public static SecondSingleton getInstance(){
            return INSTANCE;
        }
    }
    

    静的メソッドgetInstanceのすべての呼び出しに対して、同じオブジェクト参照が返されます(上記の注意は依然として使用されています).公有ドメインメソッドの主な利点は、クラスを構成するメンバーの宣言が、このクラスがSingletonであることを明確に示していることです.公有静的ドメインはfinalなので、ドメインは常に同じオブジェクト参照を含むことになります.
    以上の2つの方法については,シーケンス化時にimplements Serializableを宣言に加えるだけでは不十分である.Singletonを維持して保証するには、すべてのインスタンスドメインが瞬時(transient)であることを宣言し、readResoveインスタンスを指定する必要があります.そうしないと、インスタンスが逆シーケンス化されるたびに、新しいインスタンスが作成されます.
        private Object readResolve(){
            return INSTANCE;
        }
    
  • 単一要素を含む列挙タイプを記述する:
  •     public enum ThirdSingleton {
        INSTANCE;
        public String message = "Hello World! Third Singleton!";
    }
    

    この方法は機能的に公有ドメイン法に近いが,複雑なシーケンス化や反射攻撃に直面した場合でも,より簡潔で無償でシーケンス化機構を提供し,複数回のインスタンス化を絶対に防止する.単一要素の列挙タイプはSingletonを実現するための最良の方法となっている.
    第四条:私有化コンストラクタによる実例不可能な能力の強化
    静的メソッドと静的ドメインのみを含むクラスを記述する必要がある場合があります.これらのツールクラスはインスタンス化されたくなく、インスタンスは意味がありません.このとき,無意識のうちにインスタンス化されないように,私有化コンストラクタが必要である.
    第五条:不要なオブジェクトの作成を避ける
    一般的には、必要に応じて同じ機能の新しいオブジェクトを作成するのではなく、オブジェクトを再利用することが望ましい.
  • 可変オブジェクトの再利用:オブジェクトが可変である場合、そのオブジェクトは常に再利用可能である(単一モード、Stringオブジェクトプール)
  • .
  • は、変更されない既知の可変オブジェクトを再利用する.一部のオブジェクトを作成するコストは非常に高く、作成後も値は一般的に変わりません.この場合、このオブジェクトを再利用することで作成コストが削減されることが考えられます.
  • アダプタを使用します(アダプタとは、バックアップオブジェクトに機能を委任し、バックアップオブジェクトに代替インタフェースを提供するオブジェクトです).MapクラスのKeySetメソッドのように、Setオブジェクトを返します.Mapの場合、keyは可変ですが、keySetオブジェクトは一意で、内容が変化するだけです.
  • は、自動梱包基本タイプではなく基本タイプを優先的に使用し、無意識の自動梱包に注意します.

  • 第六条:期限切れのオブジェクト参照を削除する
    ごみ回収をサポートする言語では、メモリの漏洩は隠れています.「無意識のオブジェクト保持(unintentional object retention)」と呼ぶのが適切です.1つのオブジェクトが無意識に保持されている場合、ゴミ回収メカニズムはこのオブジェクトを処理しないだけでなく、そのオブジェクトが参照している他のすべてのオブジェクトを処理しないため、パフォーマンスに潜在的な大きな影響を及ぼす可能性があります.
    この問題は一般的にスタック、スタック、配列、チェーンテーブルなどのデータ結果がpopオブジェクトの場合に参照を除去しない.size--;のような問題の解決方法は簡単で、オブジェクトが期限切れになると、これらの参照をクリアすればstack[size--] = null;である.
    メモリ漏洩の一般的なソース:
  • クラスの自己管理メモリ.自分の管理メモリのクラスを書く必要がある場合、stackを手動で実装する場合は、要素が使用されなくなると、ごみ回収メカニズムがタイムリーに回収されるように、すぐに解放(参照を除去)することを忘れないでください.
  • キャッシュ.キャッシュ内のオブジェクトは忘れがちです.->WeakHashMapを使用してキャッシュ
  • を表します.
  • リスナーおよびその他のコールバック.APIを実装し、クライアントがこのAPIにコールバックを登録しているのに、明示的に登録をキャンセルしていない場合は、いくつかのアクションを取らない限り、それらは蓄積されます.コールバックが直ちに回収されることを保証する最善の方法は、弱い参照のみを保存することです.

  • 第七条:終結方法の使用を避ける
    エンドメソッド(finalizer)は通常予測不可能であり、危険でもある.終了方法は通常、jvm設計、構成およびプログラム実行プロセスに依存してゴミ回収メカニズムでオブジェクトを回収する際に実行を担当する.またjava仕様では、終了方法が必ず実行されるとは保証されていない.また、終了方法を使用すると、深刻なパフォーマンス損失をもたらす.オブジェクトが特定のアクションを終了する必要がある場合は、明示的な終了アクションを使用し、InputStreamインタフェースのcloseメソッドの終了メソッドなど、すべてのクライアントにインスタンスの終了時にメソッドを呼び出すように要求することができます.
  • は、明示的な終了方法の「セーフティネット(safety net)」として機能する.
  • は、重要でないローカルリソース(一般的にはローカル対等体native peerを指す)、すなわちローカルオブジェクトを終了する.