posts - 11, comments - 10, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Effective Java讀書筆記

          Posted on 2006-06-29 11:32 繁星滿空 閱讀(1032) 評論(0)  編輯  收藏 所屬分類: Java

          作者簡介:Joshua BlochGoogle的首席工程師,之前是Sun的杰出工程師,他領(lǐng)導(dǎo)了大量的java平臺設(shè)計和實現(xiàn)工作,包括jdk5.0的語言增強(qiáng)和集合框架,擁有卡內(nèi)基.梅隆大學(xué)的計算機(jī)科學(xué)的博士學(xué)位。

          ?

          本書的目標(biāo)是幫助你最有效的運用java編程語言及其基本庫,java.langjava.utiljava.io。本書由57個條目組成,每個條目傳達(dá)一個原則,這些原則是最有經(jīng)驗的程序員在實踐過程中的一些有用的做法。

          Creating and Destroying Object

          ?

          Item 1: 考慮用靜態(tài)工廠方法替代構(gòu)造器

          public static Boolean valueOf(boolean b) {

          ??? return (b?Boolean.TRUE:Boolean.FALSE);

          }

          考慮在構(gòu)造函數(shù)之外提供staticfactory mothod

          優(yōu)點:1.名字可不與類名相同,可以采用更易理解的名稱。2.不必每次都返回一個新的對象。3.可以返回子類型。

          缺點:1.無法被繼承。2.和其它static方法無法區(qū)分。

          ?

          Item 2: 通過添加私有構(gòu)造器來加強(qiáng)單例屬性(singletom property)

          public class Hello {

          public static final Hello Instance = new Hell();

          ??? private Hello() {}???????????????????????????????????????

          }

          public class Hello {

          private static final Hello Instance = new Hell();

          ??? private Hello(){}

          ??? public static Hello getInstance() {

          ??? ????return Instance;

          ??? }

          }

          第二種方法可以方便改變。

          如果想讓singleton類成為serializable,除了implements Serializable外,還要提供readResolve()方法返回該單例。

          ?

          Item 3: 為構(gòu)造器添加private以避免被實例化

          對于只是由static屬性和方法構(gòu)成的工具類,要為構(gòu)造器添加private,以免被實例化,而不添加的話,則可能有默認(rèn)的構(gòu)造器。

          ?

          ?

          Item 4: 避免創(chuàng)建重復(fù)的對象

          尤其是創(chuàng)建比較昂貴的。

          對不可修改的對象盡量進(jìn)行復(fù)用,這樣效率和性能都會提高。例如如果循環(huán)100String s = new String("hello")將創(chuàng)建100個對象 循環(huán)100String s = "hello";則只創(chuàng)建了一個對象。很好的進(jìn)行了復(fù)用。

          ?

          Item 5: 消除絕對的對象引用

          內(nèi)存泄漏,在cache里易發(fā)生。

          public Object pop(){

          if(size == 0) {}??

          ? ??return elements[size--];

          }

          public Object pop() {

          if(size == 0) {}

          ? ??Object obj = elements[--size];

          ? ??elements[size] = null;?

          ? ??return obj;

          }

          但是不要濫用,不要每個對象使用后都用NULL

          ?

          Item 6: 避免finalizer

          不要當(dāng)作C++中的析構(gòu)函數(shù),正確的方法是放在finally中。

          ?

          ?

          Methods Common to All Objects

          ?

          Item 7: 當(dāng)你覆蓋equals方法的時候一定要遵守general contact

          覆蓋equals的時候一定要加倍的小心,其實最好的辦法就是不覆蓋這個方法。比如在下面的情況下就可以不覆蓋

          ?? 1 這個類的每個實例都是唯一的,例如Thread

          ?? 2 如果你不關(guān)心這個類是否該提供一個測試邏輯相等的方法

          ?? 3 超類已經(jīng)覆蓋了equals方法,并且它合適子類使用

          ?? 4 如果這個類是private或者是package-private的,并且你確信他不會被調(diào)用

          覆蓋時遵守的原則是

          必須與自身相等,對稱性A<->B,傳遞性,一致性如果不改變始終都是一致的結(jié)果,不能與NULL相等。

          ?

          Item 8: 當(dāng)你覆蓋equals的時候必須覆蓋hashCode方法

          不這么做的話,有關(guān)hash-based的集合操作會出錯。

          契約:

          同一對象的hashCode返回相同的結(jié)果(equals比較屬性沒改變),如果equals相等,則hashCode相等,如果equals不等,則hashCode不必不等。

          ?

          ?

          Item 9: 總是覆蓋toString方法

          Object toString方法返回的形式是Class的類型加上@加上16進(jìn)制的hashcode,不利于描述對象的信息。

          ?

          Item 10: 謹(jǐn)慎覆蓋clone()方法

          盡量不要實現(xiàn),碰到deepcopy的問題。

          ?

          Item 11: 考慮實現(xiàn)覆蓋Comparable接口

          ?

          契約:傳遞性,x.compareTo(y)>0,y.compareTo(z)>0,x.compareTo(z)>0

          如果x.compareTo(y)0,則x.compareTo(z)y.compareTo(z)結(jié)果一致

          建議x.compareTo(y)0 x.equals(y)=true,但不要求。

          ?

          ?

          Classes and Interfaces

          ?

          Item 12: 把類和成員的可訪問范圍降到最低

          通常public類里不應(yīng)該有public字段,除了常量,要注意常量應(yīng)該是不可修改的。

          public class Con {

          public static final int[] data = {1,2,3};// it is bad

          public static final String hello = "world";

          public static final int i = 1;

          }

          ?

          Item 13: 偏愛不可修改的類

          5 個原則保證不可修改

          不提供可修改對象的方法,方法不可被覆蓋(final),所有字段是final,所有字段是private,確保外部不能訪問到類的可修改的組件

          好處

          可自由共享,線程安全

          ?

          Item 14: 優(yōu)先考慮合成(復(fù)合),其次是繼承

          利用wrapper class,除非確實是is a的關(guān)系。

          ?

          ?

          Item 15: 如果要用繼承那么設(shè)計以及文檔都要有質(zhì)量保證,否則就不要用繼承

          為了避免繼承帶來的問題,你必須提供精確的文檔來說明覆蓋相關(guān)方法可能出現(xiàn)的問題。

          在構(gòu)造器內(nèi)千萬不要調(diào)用可以被覆蓋的方法

          由于在Clone()或者序列化的時候非常類似構(gòu)造器的功能,因此readObject()clone()方法內(nèi)最好也不要包括能被覆蓋的方法。

          ?

          ?

          Item 16: 使用接口代替抽象類

          單重繼承

          ?

          Item 17: 接口只應(yīng)該用來定義類型

          常量不應(yīng)該放在接口中。

          ?

          Item 18: 優(yōu)先考慮靜態(tài)內(nèi)部類,而非非靜態(tài)內(nèi)部類

          ?

          ?

          Substitutes for C Constructs

          ?

          Item 19: 用類代替結(jié)構(gòu)

          ?

          Item 20: 用類繼承來代替聯(lián)合

          ?

          Item 21: 用類來代替enum結(jié)構(gòu)

          ?

          Item 22: 用類和接口來代替函數(shù)指針

          ?

          ?

          Methods

          ?

          Item 23: 檢查參數(shù)的有效性

          ?

          Item 24: 需要時使用保護(hù)性拷貝

          ?

          Item 25: 謹(jǐn)慎設(shè)計方法的簽名

          命名,不要過分提供便利的方法,避免過長參數(shù)列表

          ?

          對于參數(shù)類型,優(yōu)先使用接口而不是類

          謹(jǐn)慎的使用函數(shù)對象

          ?

          Item 26: 謹(jǐn)慎的使用重載

          ?

          Item 27: 返回零長度的數(shù)組而不是null

          ?

          Item 28: 為所有導(dǎo)出的API元素編寫文檔注釋

          當(dāng)代碼能很好的說明問題時,可不寫注釋

          ?

          ?

          General Programming

          ?

          Item 29: 將局部變量的作用域最小化

          不易閱讀,在變量聲明的時候初始化,try-catch例外

          for 循環(huán)優(yōu)于while循環(huán),for完全獨立,重用變量名不會有任何問題

          for (int i=0,n=list.size(); i<n; i++) {

          ??? dosomething(list.get(i));

          }

          ?

          Item 30: 了解和使用庫

          ?

          Item 31: 如果想要知道精確的答案,就要避免使用doublefloat

          使用int,longBigDecimal

          ?

          Item 32: 如果其他類型更適合,則盡量避免使用字符串

          如枚舉

          ?

          Item 33: 了解字符串的連接功能

          使用StringBuffer代替String

          ?

          Item 34: 通過接口引用對象

          參數(shù)、返回值,將會給函數(shù)帶來很大的靈活

          ?

          Item 35: 接口優(yōu)先于反射機(jī)制

          損失了編譯期的類型檢查的好處,性能上也會受損。

          ?

          Item 36: 謹(jǐn)慎的使用本地方法

          ?

          Item 37: 謹(jǐn)慎使用優(yōu)化

          不要因為性能而犧牲合理的代碼結(jié)構(gòu)

          ?

          Item 38: 遵守普遍接受的命名慣例

          ?

          ?

          Exceptions

          ?

          Item 39: 僅在異常情況下使用異常

          try {

          int i=0;

          while (true)

          a[i++].f();

          } catch (ArrayIndexOutOfBoundsException) {}

          利用異常終止循環(huán),不要這樣濫用異常。

          一個良好的設(shè)計不應(yīng)該依靠異常去控制流程

          ?

          Item 40: 可恢復(fù)狀態(tài)使用檢查異常(Exception),對編程錯誤使用運行期異常(RuntimeException)

          ?

          Item 41: 避免不必要的使用檢查異常

          可以先檢查是否有異常情況,而不是直接用try-catch控制程序流程

          ?

          Item 42: 盡量使用標(biāo)準(zhǔn)異常

          IllegalArgumentException 參數(shù)不合法,IllegalStateException狀態(tài)不合法

          NullPointerException 空指針,IndexOutOfBoundsException越界

          ?

          Item 43: 引發(fā)的異常要與抽象對應(yīng)

          異常的分層,lower-level high-level

          ?

          Item 44: 提供每個方法所拋出的異常的文檔

          javadoc@throws標(biāo)簽

          一般針對檢查異常

          ?

          Item 45: messages中記錄失敗捕獲的信息

          ?

          Item 46: 使失敗原子化

          即使方法調(diào)用失敗后,也要恢復(fù)對象的狀態(tài)成為調(diào)用方法前的狀態(tài)

          ?

          Item 47: 不要忽略異常

          不要catch塊內(nèi)什么都不做

          ?

          ?

          Threads

          ?

          Item 48: 同步訪問共享可變的數(shù)據(jù)

          private static int nextSerialNumber = 0;

          // 需要同步

          public static int generateSerialNumber() {

          ???? return nextSerialNumber++;

          }

          public class StoppableThread extends Thread {

          ???? private boolean stopRequested = false;

          ???? public void run() {

          ???????? boolean done = false;

          ???????? while (!stopRequested() && !done) {

          ????????????? //dosth

          ???????? }

          ???? }

          ???? // 需要同步

          ???? public synchronized void requestStop() {

          ???????? stopRequested = true;

          ???? }

          ???? private synchronized boolean stopRequested() {

          ???????? return stopRequested;

          ???? }

          }

          ?

          Item 49: 避免過度使用同步

          性能的下降

          在同步塊里盡可能少的操作

          ?

          Item 50: 不要在循環(huán)外部調(diào)用wait

          一般習(xí)慣的方法

          synchronized (obj) {

          ???? while (<condition does not hold>)

          ???????? obj.wait();

          ???? //Perform action appropriate to condition

          }

          ?

          Item 51: 不要依賴線程調(diào)度器

          ?

          Item 52: 文檔化線程安全

          如果一個類支持線程安全的話,一定要文檔說明

          ?

          Item 53: 避免使用線程組

          ?

          ?

          Serialization

          ?

          Item 54: 謹(jǐn)慎實現(xiàn)Serializable

          表面簡單implements Serializable,實際上復(fù)雜

          如果實現(xiàn)了,那私有或包私有的屬性也會成為exported API的一部分,違背了隱藏內(nèi)部實施細(xì)節(jié)的原則。

          serialVersionUID 屬性,如果代碼中不指定的話,系統(tǒng)會根據(jù)類名,實現(xiàn)接口名,成員名稱,生成一個

          即使添加一個很普通的方法,也會改變該值,這樣就失去兼容性。

          ?

          Item 55: 考慮使用自定義的序列化格式

          覆蓋writeObject()readObject()

          ?

          Item 56: 保護(hù)性地編寫readObject方法

          存在安全漏洞,反序列化

          ?

          Item 57: 必要時提供readResolve方法

          主站蜘蛛池模板: 津南区| 连平县| 罗甸县| 英德市| 六盘水市| 普格县| 东源县| 日照市| 海宁市| 台东县| 宜良县| 苍梧县| 长岭县| 龙胜| 老河口市| 玉树县| 巴彦淖尔市| 娄烦县| 井研县| 凤阳县| 梓潼县| 延寿县| 华容县| 古浪县| 如皋市| 阳山县| 钦州市| 和田市| 军事| 长治市| 正阳县| 惠来县| 上林县| 金堂县| 邛崃市| 芜湖县| 资阳市| 江山市| 临猗县| 延边| 北碚区|