Effective Java讀書筆記(1-2章-創建和銷燬對象)

      Java經典的書籍有幾本,都是很多有經驗的開發人員推薦的,包括Java編程思想,深入理解Java虛擬機,Java核心技術和Effective Java。工作之後發現自己讀的技術書籍少的可憐,因爲不愛讀書,很多基礎的知識都忘了。從最近開始,打算好好的看書,把這些經典的書籍好好的看一遍,把重要的內容記下來。以下是Effective Java的讀書筆記:


       第一章  引言

       這本書講解了78個條目的,每個條目討論一條規則,從第二章開始講解。


      第二章  創建和銷燬對象

      第1條: 考慮用靜態工廠方法代替構造器

      優點:1. 與構造器不同的第一大優勢在於,它們有名稱;

                2. 與構造器不同的第二大優勢在於,不必在每次調用它們的時候都創建一個新對象;

                3. 與構造器不同的第三大優勢在於,它們可以返回原返回類型的任何子類型的對象;

                4. 在創建參數化類型實例的時候,它們使代碼變得更加簡潔

      缺點:1. 類如果不含公有的或受保護的構造器,就不能被子類化

                2. 它們與其他的靜態方法實際上沒有任何區別

      例子如下:

import java.util.Map;					
import java.util.concurrent.ConcurrentHashMap;					
					
public class Services {					
	private Services(){				
					
	}				
					
	private static final Map<String, Provider> providers = 				
			new ConcurrentHashMap<String, Provider>();		
					
	public static final String DEFAULT_PROVIDER_NAME = "<def>";				
					
	public static void registerDefaultProvider(Provider p){				
		registerProvider(DEFAULT_PROVIDER_NAME ,p);			
	}				
					
	public static void registerProvider(String name, Provider p){				
		providers.put(name, p);			
	}				
					
	public static Service newInstance(){				
		return newInstance(DEFAULT_PROVIDER_NAME);			
	}				
					
	public static Service newInstance(String name){				
		Provider p = providers.get(name);			
		if(p == null){			
			throw new IllegalArgumentException(		
					No provider registered with name: + name);
		}			
		return p.newService();			
	}				
}	


     第2條: 遇到多個構造器參數是要考慮用構建器(靜態工廠和構造器有個共同的侷限性:它們不能很好的擴展到大量的可選參數)

     如下是幾種方法來創建類的對象

     重疊構造器模式

     例子如下

public class NutritionFacts {					
	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 NutritionFacts(int servingSize, int servings) {				
		this(servingSize, servings, 0);			
	}				
	public NutritionFacts(int servingSize, int servings, int calories) {				
		this(servingSize, servings, calories, 0);			
	}				
	public NutritionFacts(int servingSize, int servings, int calories, int fat) {				
		this(servingSize, servings, calories, fat, 0);			
	}				
	public NutritionFacts(int servingSize, int servings, int calories, int fat,				
			int sodium) {		
		this(servingSize, servings, calories, fat, sodium, 0);			
	}				
	public NutritionFacts(int servingSize, int servings, int calories, int fat,				
			int sodium, int carbohydrate) {		
		this.servingSize = servingSize;			
		this.servings = servings;			
		this.calories = calories;			
		this.fat = fat;			
		this.sodium = sodium;			
		this.carbohydrate = carbohydrate;			
	}				
					
}					
					
      JavaBean模式

      例子如下:

public class NutritionFacts {				
	private int servingSize = -1;			
	private int servings = -1;			
	private int calories = 0;			
	private int fat = 0;			
	private int sodium = 0;			
	private int carbohydrate = 0;			
	public NutritionFacts() {			
	}			
	public void setServingSize(int servingSize) {			
		this.servingSize = servingSize;		
	}			
	public void setServings(int servings) {			
		this.servings = servings;		
	}			
	public void setCalories(int calories) {			
		this.calories = calories;		
	}			
	public void setFat(int fat) {			
		this.fat = fat;		
	}			
	public void setSodium(int sodium) {			
		this.sodium = sodium;		
	}			
	public void setCarbohydrate(int carbohydrate) {			
		this.carbohydrate = carbohydrate;		
	}			
				
}				
				

       Builder模式(創建器模式)

       例子如下:

public class NutritionFacts {					
	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 int calories = 0;			
		private int fat = 0;			
		private int carbohydrate = 0;			
		private int sodium = 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 NutritionFacts build(){			
			return new NutritionFacts(this);		
		}			
	}				
					
	private NutritionFacts(Builder builder){				
		servingSize = builder.servingSize;			
		servings = builder.servings;			
		calories = builder.calories;			
		fat = builder.fat;			
		sodium = builder.sodium;			
		carbohydrate = builder.carbohydrate;			
	}				
}					

     對於構造器或者靜態工廠中具有多個參數,設計這種類的時,builder模式就是種不錯的選擇

     比重疊構造器模式比,它的客戶端代碼將更易於閱讀和編寫

     比JavaBean更加安全


     第3條: 用私有構造器或者枚舉類型強化Singleton屬性

     單例模式的2種用法(jdk1.5之前)

     1. 公有靜態成員是final域

      

public class Elvis {			
	public static final Elvis INSTANCE = new Elvis();		
			
	private Elvis(){		
			
	}		
			
	public void leaveTheBuilding(){		
			
	}		
}			
			

      2. 公有成員是個靜態工廠方法

public class Elvis {		
	private static final Elvis INSTANCE = new Elvis();	
		
	private Elvis(){	
		
	}	
		
	public static Elvis getInstance(){	
		return INSTANCE;
	}	
		
	public void leaveTheBuilding(){	
		
	}	
}		

      3. 編寫一個包含單個元素的枚舉類型

enum Elvis {		
	INSTANCE;	
		
	public void leaveTheBuilding(){	
		System.out.println("leaveTheBuilding......");
	}	
}		
		
public class A{		
	public void get(){	
		Elvis.INSTANCE.leaveTheBuilding();
	}	
	public static void main(String[] args){	
		A a = new A();
		a.get();
	}	
}		

     第4條: 通過私有構造器強化不可實例化的能力

     編寫只包含靜態方法和靜態域的類,這樣的類要求不能被實例化,這時候就可以通過把構造器定義爲私有類型就可以了,(Java裏的一些工具類不希望被實例化)

   

public class UtilityClass {
	private UtilityClass(){
		throw new AssertionError();
	}
	
}
     AssertionError是爲了防止類內部調用構造器。


    

發佈了18 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章