該書介紹了在Java編程中極具實用價值的經驗規則,這些經驗規則涵蓋了大多數開發人員每天所面臨的問題的解決方案。通過對Java平臺設計專家所使用的技術的全面描述,揭示了應該做什么,不應該做什么才能產生清晰、健壯和高效的代碼。
每天下班花點時間學習下吧,盡量在一個星期內把它看完,總結出來,大多數內容都來自書上,個人覺得該書不錯的地方摘出來。
第一條:考慮用靜態工廠方法代替構造函數
靜態工廠方法(優點):
1.每次調用的時候,不一定要創建一個新的對象,這個可以自由控制。
2.它可以返回一個原返回類型的子類型的對象。
第二條:使用私有構造函數強化singleton屬性
第一種:提供共有的靜態final域

public class Elvis
{
public static final Elvis INSTANCE = new Elvis();

private Elvis()
{

}

}
第二種:提供一個共有的靜態工廠方法
1
public class Elvis
{
2
private static final Elvis INSTANCE = new Elvis();
3
private Elvis()
{
4

5
}
6

7
public static Elvis getInstance()
{
8
return INSTANCE;
9
}
10

11
}
第一種性能上會稍微好些
第二種提供了靈活性,在不改變API的前提下,允許我們改變想法,把該類做成singleton,或者不做,容易被修改。
注意點:為了使一個singleton類變成克序列花的(Serializable),僅僅在聲明中加上implements Serializable是不夠的,
為了維護singleton性,必須也要提供一個
private Object readResolve() throws ObjectStreamException{
return INSTANCE;
}
第三條:通過私有構造函數強化不可實例化的能力
只要讓這個類包含單個顯式的私有構造函數,則它就不可被實例化;
1 public class UtilityClass{
2 private UtilityClass(){
3 
4 }
5 
6 }
企圖通過將一個類做成抽象類來強制該類不可被實例化,這是行不通的。該類可以被子類化,并且該子類也可以被實例化。
更進一步,這樣做會誤導用戶,以為這種類是專門為了繼承而設計的。
第四條:避免創建重復的對象
String s = new Sting("silly");//這么惡心的代碼就不要寫啦。。。
1.靜態工廠方法可幾乎總是優先于構造方法;Boolean.valueOf(...) > Boolean(...),構造函數每次被調用的時候都會創建一個新的對象,
而靜態工廠方法從來不要求這樣做。
2.

public class Person
{
private final Date birthDate;

public Person(Date date)
{
this.birthDate = date;
}
//don't do this

public boolean isBabyBoomer()
{
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946,Calendar.JANUARY,1,0,0,0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965,Calendar.JANUARY,1,0,0,0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >=0 && birthDate.compareTo(boomEnd) <0;
}
}
isBabyBoomer每次被調用的時候,都會創建一個新的Calendar,一個新的TimeZone和兩個新的Date實例。。。
下面的版本避免了這種低效率的動作,代之以一個static 塊初始化Calendar對象,而且最體現效率的是,他的生命周期只實例化一次Calendar并且把
80年,90年的出生的值賦值給類靜態變量BOOM_START和BOOM_END

class Person
{
private final Date birthDate;


public Person(Date birthDate)
{
this.birthDate = birthDate;
}

private static final Date BOOM_START;
private static final Date BOOM_END;

static
{
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1980, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1990, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}


public boolean isBabyBoomer()
{
return birthDate.compareTo(BOOM_START) >= 0
&& birthDate.compareTo(BOOM_END) < 0;
}

