Effective Java(一)オブジェクトの作成と破棄

4902 ワード

Tip−1はコンストラクタの代わりに静的工場法を用いることを考慮した.
  • 静的工場方法の利点
  • 静的ファクトリメソッドは名前があり、より直感的で理解しやすい
  • は、初期化時に作成する静的オブジェクト
  • を使用して、毎回新しいオブジェクトを作成する必要はない.
  • は、クラスのサブクラスオブジェクト
  • を返すことができる.
  • は、パラメータを必要とするオブジェクトを作成する際に、コード
  • を簡略化することができる.
  • 劣勢
  • プライベートクラスオブジェクトを作成できません
  • は通常の静的方法と何ら区別がなく、コンストラクタがAPIで区別を明確に識別する
  • ではなく、オブジェクトを作成できるファクトリ方法であることを発見するのは難しい.

    Tip-2コンストラクタに複数のパラメータがある場合はコンストラクタ(Builderモード)を考慮
    //   
    public class NutrilonFacts {
        private final int servingSize;
        private final int servings;
        private final int calories;
        private final int fat;
        private final int sodium;
        private final int carbohydrate;
        
        public static class Builder{
            
            //    
            private final int servingSize;
            private final int servings;
            
            //
            private final int calories = 0;
            private final int fat = 0;
            private final int sodium = 0;
            private final int carbohydrate = 0;
            
            public Builder(int servingSize,int servings){
                this.servingSize = servingSize;
                this.servings = servings;
            }
            
            //                   
            public Builder calories(int val){
                calories = val;
                return this;
            }
            
            public Builder fat(int val){
                fat = val;
                return this;
            }
            
            public Builder carbohydrate(int val){
                carbohydrate = val;
                return this;
            }
            
            public Builder sodium(int val){
                sodium = val;
                return this;
            }
            
            public NutrilonFacts build(){
                return new NuuritionFacts(this);
            }
            
        }
        
        private NutritionFacts(Builder builder){
            servingSize = builder.servingSize;
            servings = builder.servings;
            calories = builder.calories;
            fat = builder.fat;
            sodium = builder.sodium;
            carbohydrate = builder.carbohydrate;
        }
    }
    
    
    //    
    NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).calories(100).sodium(35).carbohydrate(27).build();
    
    
  • のメリット
  • builderモードは、名前付きのオプションパラメータを実現し、コンストラクタのマルチパラメータの実現と読みやすさ
  • を簡略化する.
  • JavaBeanのsettingメソッドモードよりも安全
  • 劣勢
  • Builderモードは、オーバーラップコンストラクタモードよりも冗長である可能性があり、Builderモード
  • を使用する必要があるのは4つ以上のパラメータのみである.
  • 将来クラスに複数の追加可能なパラメータがある場合は、最初からBuilderモード
  • を使用することが望ましい.
    Tip-3プライベートコンストラクタまたは列挙による単例モードの強化
    シングル・インスタンス・モードを実現するには2つの方法があります.
  • プライベートコンストラクタ+共有静的メンバーオブジェクト
  • public class Elvis{
        
        public static final Elvis INSTANCE = new Elvis();
        
        private Elvis(){....}
        
        public void leaveTheBuilding(){.....}
        
    }
    
  • スタティックファクトリメソッド+プライベートスタティックメンバーオブジェクト
  • 
    public class Elvis{
        
        private static final Elvis INSTANCE = new Elvis();
        
        private Elvis(){....}
        
        public static Elvis getInstance(){ return INSTANCE;}
        
        public void leaveTheBuilding(){.....}
        
    }
    
    

    基本的なモノリシックモードは、逆シーケンス化すると、新しいオブジェクトが作成され、複数のモノリシックオブジェクトが発生することを防止するために、2つの解決策がある.
  • クラスにreadResolve()メソッド
  • を追加
    private Object readResolve(){
         return INSTANCE;
    }
    
  • 単一要素を含む列挙タイプ
  • を記述する
    
    //           ,            ,         
    //                        
    public enum Elvis{  
    
        INSTANCE;
        
        public void leaveTheBuilding(){
            .....
        }
        
    }
    
    

    Tip-4は、プライベートコンストラクタによって単一のパターンを実現する(so easyは記録しない)
    Tip-5不要なオブジェクトの作成を避ける
    //    
    
    //                String   
     String s = new String("stringette");
    
    //            
     String s = "stringette";
    

    Integerのような梱包タイプではなく、基本データ型を優先的に使用するには、パフォーマンスの差が顕著です.
    データベース接続プールスレッドプールは、両方のオブジェクトの作成コストが非常に高いため、オブジェクトの再利用です.
    Tip-6期限切れのオブジェクト参照を消去
    //          null
    String s = new String("ddd");
    s = null;
    
  • のメリット
  • メモリオーバーフロー防止、プログラム実行失敗
  • これらのオブジェクトが再び誤って参照されると、こっそりと誤って実行するのではなく、NPE空のポインタ異常が直ちに投げ出されます.

  • メモリオーバーフローの一般的なソース
  • クラスの自己管理メモリでは、メモリオーバーフロー
  • が発生する可能性があります.
  • キャッシュによるメモリオーバーフローは、オブジェクトをキャッシュに入れると忘れやすくなり、メモリオーバーフローを引き起こすため、weakHashMapは特殊な場合にこのような問題を解決することができる
  • .
  • プログラムのリスナーやその他のコールバックは、apiにコールバックを登録する、表示せずに登録をキャンセルすると蓄積し、メモリオーバーフロー
  • を招く.
  • heap分析ツール、プログラムメモリオーバーフローの可能性を分析できる

  • Tip-7エンドメソッドの使用を避ける(finally)
    try{
        
    }finally{
        
    }
    
    // JVM         ,                           
    
  • 結論:重要な持続状態を更新するために、終了方法に依存するべきではない.たとえば、finallyに依存して共有リソース(データベースなど)上の永続的なロックを解放すると、分散システム全体が崩壊しやすくなります.
  • System.gcとSystem.runFinalizationはfinallyが実行される機会を増やしたが、必ずしも実行されるとは保証されず、唯一finallyが実行されることを保証する方法はSystem.runFinalizersOnExitおよびRuntime.runFinalizersOnExitであると主張している.しかし、この2つの方法の闘志の致命的な欠陥は、すでに廃棄されている.
  • finallyを使用すると、非常に深刻なパフォーマンス損失があります.