posts - 73,  comments - 55,  trackbacks - 0

          第一章 一般技術(shù)
          1.java只有唯一一種參數(shù)傳遞方式:by value(值傳遞)。對于primitive types(基本型別)很容易理解,對于object references(對象引用),傳遞的是object reference的拷貝。
          2.polymorphism(多態(tài))優(yōu)于instanceof:instanceof很容易被誤用,很多場合都應(yīng)該以多態(tài)代替,無論何時(shí)看到instanceof,請判斷是否可以改進(jìn)以消除它。
          3.避免創(chuàng)建重復(fù)對象。比如一個(gè)類A的某個(gè)方法新建了一個(gè)類B,且此類B不會改變,則每次建立該類A的一個(gè)對象就會新建B的對象,此時(shí)應(yīng)把
          B設(shè)為private static final。
          4.清除過期的對象引用。
          5.避免使用終結(jié)函數(shù)。因?yàn)榻K結(jié)函數(shù)可能得不到執(zhí)行或很久后得到執(zhí)行,所以要避免使用。顯示的中止方法通常與try-finally結(jié)構(gòu)結(jié)合使用,防止出現(xiàn)異常時(shí)終結(jié)函數(shù)得不到執(zhí)行。
          eg: Foo foo = new Foo(...);
          ??? try{
          ??????? //do what must be done with foo???
          ??? }finally{
          ??????? foo.terminate();
          ??? }
          6.通過私有構(gòu)造函數(shù)來強(qiáng)化不可實(shí)例化的能力。比如一些工具類不希望被實(shí)例化,然而在缺少顯示構(gòu)造函數(shù)時(shí)編譯器會自動提供一個(gè)默認(rèn)構(gòu)造函數(shù),為防止以上情況要構(gòu)造一個(gè)顯示的私有的構(gòu)造函數(shù)。
          eg:public class UtilityClass{
          ???? private UtilityClass(){
          ???? }
          ?? }
          7.通過私有構(gòu)造函數(shù)強(qiáng)化singleton屬性。singleton是指這樣的類,它只能實(shí)例化一次。singleton通常被用來代表那些本質(zhì)上具有唯一性的系統(tǒng)組件,比如視頻顯示或者文件系統(tǒng)。
          ? eg:public class Elvis{
          ?????? public static final Elvis INSTANCE = new Elvis();
          ?????? private Elvis(){
          ?????? }
          ???? }
          8.考慮用靜態(tài)工廠方法代替構(gòu)造函數(shù),但如果沒有其他強(qiáng)烈的因素,最好還是簡單的使用構(gòu)造函數(shù),畢竟它是語言規(guī)范。靜態(tài)工廠方法實(shí)際上是一個(gè)簡單的靜態(tài)方法,他返回的是類的一個(gè)實(shí)例。
          ? 有點(diǎn):a.與構(gòu)造函數(shù)不同,靜態(tài)工廠方法具有名字。
          ??????? b.與構(gòu)造函數(shù)不同,它們每次被調(diào)用的時(shí)候不要求非得創(chuàng)建一個(gè)對象。
          ??????? c.與構(gòu)造函數(shù)不同,與構(gòu)造函數(shù)不同,它們可以返回一個(gè)原類型的子類型對象。
          第二章 所有對象都通用的方法(equals(),hashCode(),toString(),clone(),Comparable接口)
          一.按規(guī)則使用equals():
          1.使用equals的規(guī)則:
          ? a.如果一個(gè)class的兩個(gè)對象占據(jù)不同的內(nèi)存空間也可被視為邏輯相等的話,那么得為這個(gè)class提供一個(gè)equals()
          ? b.檢查是否等于this
          ? c.比較關(guān)鍵域以判斷兩個(gè)對象是否相等
          ? d.如果有java.lang.Object以外的任何base class實(shí)現(xiàn)了equals(),那么就應(yīng)該調(diào)用super.equals()
          ? e.如果只允許同一個(gè)class所產(chǎn)生的對象被視為相等,則通常使用getClass()
          ??? eg1:一般情況
          ??? public boolean equals(Object obj){
          ??????? if(this == obj){
          ????????? return true;
          ??????? }
          ??????? if(obj != nul && getClass() == obj.getClass()){
          ????????? Test test = (Test)obj;
          ????????? if(***){//相等條件
          ????????????? return true;
          ????????? }
          ??????? }
          ??????? return false;
          ????? }
          ??? eg2:調(diào)用super.equals()情況
          ??? public boolean equals(Object obj){
          ????? if(super.equals(obj)){//已經(jīng)包含了this == obj; obj !=null && getClass() == obj.getClass()的判斷
          ??????? Test test = (Test)obj;
          ????????? if(***){//相等條件
          ????????????? return true;
          ????????? }
          ??????? }
          ??????? return false;
          ????? }

          ? f.只有在不得不對derived class對象與base classes對象進(jìn)行比較的場合中,才使用instanceof,并且你應(yīng)該明白這樣做帶來的可能問題和復(fù)雜性,并且derived class和base classes都用instanceof實(shí)現(xiàn)equals()時(shí),這種比較不會展現(xiàn)“對稱相等性”。
          ??? Base b;Derived d;//分別表示父類、子類
          ??? 1)父類實(shí)現(xiàn)equals,子類繼承父類的equals,b.equals(d) == d.equals(d);
          ??? 2)父類子類分別實(shí)現(xiàn)了equals,b.equals(d) != d.equals(b);
          ??? 3)父類未實(shí)現(xiàn)equals,子類實(shí)現(xiàn)了equals,b.equals(d) != d.equals(b);
          2.對于既不是float也不是double類型的primitive types,使用==操作符;對于對象引用域,可以遞歸的調(diào)用equals方法;對于float域,先使用Float.floatToIntBits轉(zhuǎn)換成int類型值,然后使用==操作符比較int類型的值;對于double域,先使用Double.doubleToLongBits轉(zhuǎn)換成int類型的值,然后使用==操作符比較long類型的值.(這是由于存在Float.NaN、-0.0f以及類似的double類型的常量)
          二.hashCode():
          1。改寫equals時(shí)總是要改寫hashCode方法,如果不這樣作,會導(dǎo)致該類無法與所有基于散列值(hash)的集合類在一起正常工作,這樣的集合類包括HashMap、HashSet、HashTable
          2。hashCode方法的簡單方法:
          ? 1。把某個(gè)非零數(shù)值(比如17),保存在int result變量里。
          ? 2。對于對象中每一個(gè)關(guān)鍵域f(指equals方法中考慮的每一個(gè)域),完成以下步驟:
          ? a)為該域計(jì)算int類型的散列碼c:
          ??? i.該域?yàn)閎oolean型,c = f ? 0 : 1
          ??? ii.byte, char, short, int型, c = (int)f
          ??? iii.long型, c = (int)(f ^ (f >>> 32))
          ??? iv.float型, c = Float.floatToIntBits(f)
          ??? v.double型, Double.doubleToLongBits(f)得到long型,然后按iii計(jì)算散列值
          ??? vi.如果是對象引用,c = (this.*** == null) ? 0 : this.***.hashCode();
          ??? vii.如果該域是個(gè)數(shù)組,則把其中每一個(gè)元素當(dāng)作單獨(dú)的域來處理
          ?? b)result = 37 * result + c;//把每個(gè)c都組合到result中
          ?? 3。返回result
          ?? eg1:
          ?public int hashCode() {
          ???? int result = 17;
          ???? //對于關(guān)鍵域是id的情況
          ???? int idValue = (this.getId() == null) ? 0 : this.getId().hashCode();
          ???? result = (result * 37) + idValue;
          ???? //如果還有第二個(gè)關(guān)鍵域name
          ???? //int nameValue = (this.getName() == null) ? 0 : this.getName().hashCode();
          ???? //result = (result * 37) + nameValue;
          ???? this.hashValue = result;
          ?return this.hashValue;
          ?}
          ??? eg2:
          ?如果一個(gè)類是非可變的,并且計(jì)算散列碼代價(jià)較大,則應(yīng)把散列碼存到對象內(nèi)部:
          ?private int hashValue = 17;//先定義hashValue,不需要get/set方法
          ?........................
          ?public int hashCode() {//對于關(guān)鍵域是id的情況
          ???? if (this.hashValue == 17) {
          ??int result = 17;
          ??int idValue = (this.getId() == null) ? 0 : this.getId().hashCode();
          ??result = (result * 37) + idValue;
          ??//如果還有第二個(gè)關(guān)鍵域name
          ??//int nameValue = (this.getName() == null) ? 0 : this.getName().hashCode();
          ??//result = (result * 37) + nameValue;
          ??this.hashValue = result;
          ???? }
          ???? return this.hashValue;
          ?}
          三。toString():會使這個(gè)類用起來更加方便。
          四。謹(jǐn)慎的改寫clone()。實(shí)現(xiàn)拷貝的方法有兩個(gè):一是實(shí)現(xiàn)cloneable接口(effective java 39頁,沒仔細(xì)看),二是提供拷貝構(gòu)造函數(shù)
          ? public Yum(Yum yum);
          ? 或是上面的微小變形:提供一個(gè)靜態(tài)工廠來代替構(gòu)造函數(shù):
          ? public static Yum newInstance(Yum yum);
          五、用到搜索、排序、計(jì)算極值的情況時(shí),考慮實(shí)現(xiàn)Comparable接口。
          public int compareTo(Object o)//方法不需要手工檢查參數(shù)的類型,如參數(shù)類型不符合會拋出ClassCastException;如參數(shù)為null,該方法拋出NullPointerException。
          第三章 類和接口
          1。使類和成員(變量、方法、內(nèi)部類、內(nèi)部接口)的可訪問能力最小化。
          2。private和friendly成員都是一個(gè)類實(shí)現(xiàn)中的一部分,并不會影響到導(dǎo)出API。然而,如果這些域所在的類實(shí)現(xiàn)了Serializable接口,那么這些成員可能會被泄漏到導(dǎo)出API中。
          3。如果一個(gè)方法改寫了超類中的一個(gè)方法,那么子類中該方法的訪問級別不能低于父類中該方法的訪問級別。特別是:類實(shí)現(xiàn)了接口,那么接口中的方法在這個(gè)類中必須聲明為公有的,因?yàn)榻涌谥蟹椒J(rèn)為public abstract。
          六、異常處理
          1.決不可忽略異常,即catch后什么也不做。
          2.決不可掩蓋異常
          try{
          ? e1;//異常1
          ? e2;//異常2
          }catch(Exception e){
          ? e.printStackTrace()
          }//只能捕獲異常2
          辦法:要仔細(xì)分析,用棧來保存異常
          3.覆寫異常處理時(shí):
          父類不拋出異常時(shí),自類不能拋出異常。
          父類拋出異常時(shí),自類三種情況:a)不拋出異常b)拋出父類異常c)拋出父類異常的派生異常。
          4.只要有finally塊就一定會進(jìn)入,即使try-catch塊有return/break/continue語句。
          5.養(yǎng)成將try/catch塊放在循環(huán)外的習(xí)慣,在不啟動JIT時(shí)節(jié)省時(shí)間。

          posted on 2006-12-05 16:16 保爾任 閱讀(174) 評論(0)  編輯  收藏 所屬分類: J2SE

          <2006年12月>
          262728293012
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 通河县| 嘉荫县| 邳州市| 旌德县| 湾仔区| 武宁县| 澜沧| 杭锦后旗| 宁海县| 怀远县| 珠海市| 墨竹工卡县| 金华市| 文昌市| 弥勒县| 锡林郭勒盟| 旬阳县| 都安| 禄丰县| 龙川县| 海伦市| 隆化县| 阿合奇县| 达日县| 东源县| 绍兴县| 沙田区| 砀山县| 丰镇市| 蒙山县| 西丰县| 图木舒克市| 汝南县| 江津市| 景东| 苏尼特左旗| 新丰县| 马尔康县| 女性| 娱乐| 邢台县|