Effective JAVA
Effective JAVA
第2章 創(chuàng)建銷毀對象
1.考慮用靜態(tài)工廠方法代替構(gòu)造器
優(yōu)點(diǎn)
·靜態(tài)工廠方法有名稱
·不用每次都創(chuàng)建新實(shí)例
·可以返回遠(yuǎn)返回類型的任何子類型的對象
·在創(chuàng)建參數(shù)化類型實(shí)例的時(shí)候代碼更簡潔
缺點(diǎn)
·不能被子類化
·它們與其他的靜態(tài)方法實(shí)際上沒有任何區(qū)別
2.遇到多個(gè)構(gòu)造器參數(shù)時(shí)要考慮用構(gòu)造器
如果類的構(gòu)造器或者靜態(tài)工廠中具有多個(gè)參數(shù),可以考慮使用Builder模式
3.用私有構(gòu)造器或者枚舉類型強(qiáng)化Singleton屬性
編寫一個(gè)包含單個(gè)元素的枚舉類型
public enum Elvis{
INSTANCE;
public void leaveTheBuilding*(){
...}
}
">public enum Elvis{
INSTANCE;
public void leaveTheBuilding*(){
...}
}
4.通過私有構(gòu)造器強(qiáng)化不可實(shí)例化的能力
讓不需要實(shí)例化的類擁有私有(private)構(gòu)造器來避免被實(shí)例化
//Noninstantiable utility class
public enum UtilityClass{
private UtilityClass(){
throw new AssertinError();
}
...
}
">//Noninstantiable utility class
public enum UtilityClass{
private UtilityClass(){
throw new AssertinError();
}
...
}
5.避免創(chuàng)建不必要的對象
使用靜態(tài)的初始化器(initialize)避免創(chuàng)建重復(fù)的Calendar,TimeZone和Date實(shí)例
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Person {
private Date birthDate;
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) <= 0;
}
}
">import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Person {
private Date birthDate;
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) <= 0;
}
}
優(yōu)先使用基本類型而不是裝箱基本類型,要當(dāng)心無意識的自動裝箱。
6.消除過期的對象引用
一旦對象引用已經(jīng)過期,只需清空這些引用即可。
7.避免使用終結(jié)方法
終結(jié)方法(finalizer)通常是不可預(yù)測的,也是很危險(xiǎn)的,一般情況下是不必要的。
不應(yīng)該依賴終結(jié)方法來更新重要的持久狀態(tài)。
顯式終止方法的典型例子:InputStream,OutputStream,java.sql.Connection的Close
第3章 對于所有對象都通用的方法
8.覆蓋equals時(shí)請遵守通用約定
·類的每個(gè)實(shí)例本質(zhì)上都是唯一的
·不關(guān)心類是否提供了“邏輯相等”
·超類已經(jīng)覆蓋了equals,從超類繼承過來的行為對于子類也是合適的
·類是私有的或是包級私有的,應(yīng)該覆蓋父類的equals方法保證永遠(yuǎn)不會被調(diào)用
9.覆蓋equals時(shí)總要覆蓋hashCode
10.始終要覆蓋toString
11.謹(jǐn)慎地覆蓋clone
12.考慮實(shí)現(xiàn)Comparable接口
第4章 類和接口
13.使類和成員的可訪問性最小化
14.在公有類中使用訪問方法而非公有域
15.使可變性最小化
1.不要提供任何會修改對象狀態(tài)的方法
2.保證類不會被擴(kuò)展
3.使所有域都是final
4.使所有域都成為私有的
5.確保對于任何可變組建的互斥訪問
16.復(fù)合優(yōu)先于繼承
17.要么為繼承而設(shè)計(jì),并提供文檔說明,要么就禁止繼承
18.接口優(yōu)于抽象類
- 現(xiàn)有的類可以很容易被更新,以實(shí)現(xiàn)新的接口
- 接口是定義minin(混合類型)的理想選擇
- 接口允許我們構(gòu)造非層次結(jié)構(gòu)的類型框架
19.接口只用于定義類型
20.類層次優(yōu)于標(biāo)簽類
21.用函數(shù)對象表示策略
22.優(yōu)先考慮靜態(tài)成員類
第5章 泛型
23.請不要在新代碼中使用原生態(tài)類型
24.消除非受檢警告
SuppressWarnings注解始終在盡可能小的范圍中使用。
25.列表預(yù)先于數(shù)組
數(shù)組是協(xié)變得(covariant)。
數(shù)組是具體化的。
26.優(yōu)先考慮泛型
27.優(yōu)先考慮泛型方法
28.利用有限制通配符來提升API的靈活性
29.優(yōu)先考慮類型安全的已購容器
第6章 枚舉和注解
30.用enum代替int常量
31.用實(shí)例域代替序數(shù)
32.用EnumSet代替位域
33.用EnumMap代替序數(shù)索引
34.用接口模擬可伸縮的枚舉
35.注解優(yōu)先于命名模式
36.堅(jiān)持使用Override注解
37.用標(biāo)記接口定義類型
第7章 方法
38.檢查參數(shù)的有效性
39.必要時(shí)進(jìn)行保護(hù)性拷貝
40.謹(jǐn)慎設(shè)計(jì)方法簽名
謹(jǐn)慎地選擇方法的名稱
不要過于追求提供便利的方法
避免過長的參數(shù)列表
41.慎用重載
42.慎用可變參數(shù)
43.返回零長度的數(shù)組或集合,而不是null
44.為所有到處的API元素編寫文檔注釋
第8章 通用程序設(shè)計(jì)
45.將局部變量的作用域最小化
46.for-each循環(huán)優(yōu)先于傳統(tǒng)的for循環(huán)
無法使用for-each的情形
1.過濾
2.轉(zhuǎn)換
3.平行迭代
47.了解和使用類庫
48.如果需要精確的答案,請避免使用float和double
正確的做法:使用BigDecimal,int或者long進(jìn)行貨幣計(jì)算
49.基本類型優(yōu)先于裝箱基本類型
50.如果其他類型更適合,則盡量避免使用字符串
字符串不適合替代其他的值類型
字符串不適合代替枚舉類型
字符串不適合替代聚集類型
字符串也不適合太呆能力表(capabilities)
51.當(dāng)心字符串連接的性能
52.通過接口引用對象
53.接口優(yōu)先于反射機(jī)制
反射機(jī)制的代價(jià)
喪失了編譯時(shí)類型檢查的好處
執(zhí)行反射訪問所需要的代碼非常笨拙和冗長
性能損失
54.謹(jǐn)慎地使用本地方法
55.謹(jǐn)慎地進(jìn)行優(yōu)化
56.遵守普遍接受的命名慣例
第9章 異常
57.只針對異常的情況才使用異常
58.對可恢復(fù)的情況使用受檢異常,對編程錯(cuò)誤使用運(yùn)行時(shí)異常
JAVA提供了三種可拋出結(jié)構(gòu)(throwable)
1.受檢的異常(checked exception)
2.運(yùn)行時(shí)異常(run-time exception)
3.錯(cuò)誤(error)
59.避免不必要地使用受檢的異常
60.優(yōu)先使用標(biāo)準(zhǔn)的異常
61.拋出與抽象相對應(yīng)的異常
62.每個(gè)方法拋出的異常都要有文檔
63.在細(xì)節(jié)信息中包含能捕獲失敗的信息
64.努力使失敗保持原子性
65.不要忽略異常
第10章 并發(fā)
66.同步訪問共享的可變數(shù)據(jù)
關(guān)鍵字synchronized可以保證在同一時(shí)刻,只有一個(gè)線程可以執(zhí)行某一個(gè)方法,或者某一個(gè)代碼塊。
67.避免過度同步
68.executor和task優(yōu)先于線程
69.并發(fā)工具優(yōu)先于wait和notify
70.線程安全性的文檔化
71.慎用延遲初始化
72.不要依賴于線程調(diào)度器
73.避免使用線程組
第11章 序列化
74.謹(jǐn)慎地實(shí)現(xiàn)Serializable接口
代價(jià)
1.實(shí)現(xiàn)Serializable接口而付出的最大代價(jià)是,可改變性變低
2.增加了出現(xiàn)Bug和安全漏洞的可能性
3.隨著類發(fā)行新的版本,相關(guān)的測試負(fù)擔(dān)也增加了
75.考慮使用自定義的序列化形式
76.保護(hù)性地編寫readObject方法
77.對于實(shí)例控制,枚舉類型優(yōu)先于readResolve
78.考慮用序列化代理代替序列化實(shí)例
posted on 2016-08-26 18:45 Lucky 閱讀(243) 評論(0) 編輯 收藏 所屬分類: java