posts - 73,  comments - 55,  trackbacks - 0

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

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

          posted on 2006-11-07 11:29 保爾任 閱讀(133) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 定安县| 鄂托克前旗| 丰都县| 江口县| 弋阳县| 施秉县| 崇信县| 高雄市| 南投市| 新蔡县| 巨野县| 扎鲁特旗| 米脂县| 衡山县| 冀州市| 喜德县| 霞浦县| 台南市| 仙游县| 吉隆县| 讷河市| 靖西县| 马边| 方正县| 樟树市| 美姑县| 玉龙| 读书| 武强县| 隆林| 孟连| 中卫市| 博乐市| 仁怀市| 乐至县| 莱芜市| 泗水县| 新田县| 金乡县| 巨鹿县| 天全县|