java編程規范

          Posted on 2009-02-17 19:52 鄒江平 閱讀(339) 評論(0)  編輯  收藏

           

           本文介紹的Java規則的說明分為5個級別,級別1是最基本也是最重要的級別,在今后將陸續寫出其他的規則。遵守了這些規則可以提高程序的效率、使代碼有更好的可讀性等。

            (1) 避免使用NEW關鍵字來創建String對象

            把一個String常量copy到String 對象中通常是多余、浪費時間的。

          Public class test{
           Public void method(){
            System.out.print (str);
           }
           private String str = new String ("1"); //這里新建對象是完全沒有必要的
           private String str2=”2” //正確的應該如此
          }

            (2) 避免使用不必要的嵌套

            過多的嵌套會使你的代碼復雜化,減弱可讀性。

          Public class test {
           String add (){
            Int c=(a=a+b)+b; //過于復雜
            Return c
           }
          }

            (3) 避免在同一行聲明不同類型的多個變量

            這樣可以使程序更加清晰,避免混亂

          private int index, index1[];

            正確的應該如此:

          private int index;
          private int index1[];

            (4) 在每一行里寫一條語句

            這條規則不包括for語句:比如:'for (int i = 0; i < 10; i++) x--;’可以增加代碼的可讀性。

          public class OSPL {
           int method (int a, int b) {
            int i = a + b; return i; // 可讀性不強
           }

            正確的:

          public class OSPLFixed {
           int method (int a, int b) {
            int i = a + b;
            return i;
           }
          }

            (5)經常從finalize ()中調用super.finalize ()

            這里的finalize ()是java在進行垃圾收集的時候調用的,和finally不一樣。如果你的父類沒有定義finally()的話,你也應該調用。這里有兩個原因:(1)在不改變代碼的情況下能夠將父類的finally方法加到你的類中。(2)以后你會養成習慣調用父類的finally方法,即使父類沒有定義finally方法的時候。

            正確的方法應該如此:

          public class parentFinalize {
           protected void finalize () throws Throwable {
            super.finalize(); // FIXED
           }

            (6) 不要在finalize ()中注銷listeners

            不要再finalize ()方法中中注銷listeners,finalize ()只有再沒有對象引用的時候調用,如果listeners從finalize()方法中去除了,被finalize的對象將不會在垃圾收集中去除。

          public void finalize () throws Throwable {
           bButton.removeActionListener (act);
          }

            (7) 不要顯式的調用finalize ()方法

            雖然顯式的調用這個方法可以使你確保你的調用,但是當這個方法收集了以后垃圾收集會再收集一次。

          public class T7 {
           public void finalize() throws Throwable {
            close_resources ();
            super.finalize ();
           }
           public void close_resources() {}
          }
          class Test {
           void cleanup () throws Throwable {
            t71.finalize(); // 調用
            t71 = null;
           }
           private t71 = new T7 ();
          }

            對于這樣的調用我們應該自己創建一個釋放的方法,做最初finalize ()所作的事情,當你每次想顯式的調用finalize ()的時候實際上調用了釋放方法。然后再使用一個判斷字段來確保這個方法只執行一次,以后再調用就沒關系了。

          public class T7 {
           public synchronized void release () throws Throwable{
            if (!_released) {
             close_resources (); // do what the old 'finalize ()'
             did _released = true;
            }
           }
           public void finalize () throws Throwable {
            release ();
            super.finalize ();
           }
           public void close_resources() {}
           private boolean _released = false;
          }
          class TestFixed {
           void closeTest () throws Throwable {
            t71 .release (); // FIXED
            t71 = null;
           }
           private T7 t71 = new T7 ();
          }

            (8)不要使用不推薦的API

            盡量使用JDK1.3推薦的API。在類和方法或者java組件里有很多方法是陳舊的或者是可以選擇的。有一些方法SUN用了"deprecated“標記。最好不要使用例如:

          private List t_list = new List ();
          t_list.addItem (str);

            如果查一下javadoc的話,會發現建議用add()來代替addItem()。

            (9)為所有序列化的類創建一個'serialVersionUID'

            可以避免從你各種不同的類破壞序列的兼容性。如果你不特別制訂一個UID的話,那么系統為自動產生一個UID(根據類的內容)。如果UID在你新版本的類中改變了,即使那個被序列化的類沒改變,你也不能反序列化老的版本了。

          public class DUID implements java.io.Serializable { public void method () {}}

            在里面加一個UID,當這個類的序列化形式改變的時候,你也改變這個UID就可以了。

          public class DUIDFixed implements java.io.Serializable {
           public void method () {}
           private static final long serialVersionUID = 1;
          }

            (10)對于private常量的定義

            比較好的做法是對于這樣的常量,加上final標記,這樣的常量從初始化到最后結束值都不會改變。

          private int size = 5;

            改變后的做法是:

          private final int size = 5;

            (11)避免把方法本地變量和參數定義成和類變量相同的名字

            這樣容易引起混擾,建議把任何的變量字都定義成唯一的。這樣看來,SCJP里的那些題目在現實中就用不到了:)

          public void method (int j) { final int i = 5; // VIOLATION } private int j = 2;

            建議:

          public void method (int j1) { final int i = 5; // VIOLATION } private int j = 2;

          1. 應用范圍

          本規范應用于采用J2EE規范的項目中,所有項目中的JAVA代碼(含JSP,SERVLETJAVABEAN,EJB)均應遵守這個規范。同時,也可作為其它項目的參考。

          2. 設計類和方法

          2.1     創建具有很強內聚力的類

          方法的重要性往往比類的重要性更容易理解,方法是指執行一個統一函數的一段代碼。類常被錯誤的視為是一個僅僅用于存放方法的容器。有些開發人員甚至把這種思路作了進一步的發揮,將他們的所有方法放入單個類之中。

          之所以不能正確的認識類的功能,原因之一是類的實現實際上并不影響程序的執行。當一個工程被編譯時,如果所有方法都放在單個類中或者放在幾十個類中,這沒有任何關系。雖然類的數量對代碼的執行并無太大的影響,但是當創建便于調試和維護的代碼時,類的數量有時會帶來很大的影響。

          類應該用來將相關的方法組織在一起。

          當類包含一組緊密關聯的方法時,該類可以說具有強大的內聚力。當類包含許多互不相關的方法時,該類便具有較弱的內聚力。應該努力創建內聚力比較強的類。

          大多數工程都包含許多并不十分適合與其他方法組合在一起的方法。在這種情況下,可以為這些不合群的方法創建一個綜合性收容類。

          創建類時,應知道模塊化這個術語的含義是什么。類的基本目的是創建相當獨立的程序單元。

          2.2     創建松散連接和高度專用的方法

          1.       使所有方法都執行專門的任務

          每個方法都應執行一項特定的任務,它應出色的完成這項任務。應避免創建執行許多不同任務的方法。

          創建專用方法有許多好處。首先調試將變得更加容易。

          2.       盡量使方法成為自成一體的獨立方法

          當一個方法依賴于其他方法的調用時,稱為與其他方法緊密連接的方法。緊密連接的方法會使調試和修改變得比較困難,因為它牽涉到更多的因素。松散連接的方法優于緊密連接的方法,但你不可能使每個方法都成為獨立的方法。

          若要使方法具備較強的獨立性,方法之一是盡量減少類變量。

          創建方法時,設法將每個方法視為一個黑箱,其他例程不應要求了解該方法的內部工作情況,該方法也不應要求了解它外面的工程情況。這就是為什么你的方法應依靠參數而不應依靠全局變量的原因。

          創建專用方法時,請考慮下列指導原則:

          1)    將復雜進程放入專用方法。如果應用程序使用復雜的數學公式,請考慮將每個公式放入它自己的方法中。這樣使用這些公式的其他方法就不包含用于該公式的實際代碼。這樣也可以更容易發現與公式相關的問題。

          2)    將數據輸入/輸出(I/O)放入專用方法。

          3)    將專用方法中可能要修改的代碼隔離。如果你知道某個進程經常變更,請將這個多變的代碼放入專用方法,以便以后可以更容易的進行修改,并減少無意中給其他進程帶來問題的可能性。

          4)    將業務規則封裝在專用方法中。業務規則常屬于要修改的代碼類別,應與應用程序的其余部分隔開。其他方法不應知道業務規則,只有要調用的方法才使用這些規則。

          3.       設計類和方法時,要達到下列目的:

          1)    創建更加容易調試和維護的方法

          2)    創建具有強大內聚力的類

          3)    創建高度專用的方法

          4)    創建松散連接的方法

          5)    盡量使方法具有獨立性

          6)    提高方法的扇入性

          7)    降低方法的扇出性

          2.3     編程原則

          1.       為方法和類賦予表義性強的名字

          為了使代碼更加容易理解,最容易的方法之一是為你的方法賦予表義性強的名字。函數名DoIt、GetIt的可讀性很難與CalculateSalesTax、 RetrieveUserID相比。

          由縮寫方法名組成的代碼很難理解和維護,沒有理由再這樣做了。

          給方法正確的命名,可使程序工程的調試和維護工作大大的改觀。請認真對待方法命名的工作,不要為了減少鍵入操作量而降低方法的可理解度。

          實際應用舉例:

          1)    給方法命名時應大小寫字母混合使用。如果句子全使用大寫字母,那么閱讀起來就非常困難,而大小寫字母混合使用的句子,閱讀起來就很容易。

          2)    定義方法名時不要使用縮寫。如果你認為應用程序中的某些工程應使用縮寫,那么請將這些情況加上注釋,并確保每個人在所有時間內都使用這些縮寫。決不要在某些方法中對某些單詞進行縮寫,而在別的方法中卻不使用縮寫。

          2.       為每個方法賦予單個退出點

          3.       創建方法時,始終都應顯式地定義它的作用域。

          1)    如果你真的想創建一個公用方法,請向代碼閱讀者說明這一點。

          2)    通過為每個方法賦予一個明確定義的作用域,可以減少代碼閱讀者需要投入的工作量。應確保你為方法賦予最有意義的作用域。如果一個方法只被同一類中的另一個方法調用,那么請將它創建成私有方法。如果該方法是從多個類中的多個方法中調用,請將該說明為公用方法。

          4.       用參數在方法之間傳遞數據

          應盡量避免使用類變量。一般來說,變量的作用域越小越好。為了減少類變量,方法之一是將數據作為參數在不同方法之間傳遞,而不是讓方法共享類變量。

          1)    為每個參數指定數據類型。

          2)    始終要對數進行檢驗,決不要假設你得數據沒有問題。程序員常犯的一個錯誤是在編寫方法時假設數據沒有問題。在初始編程階段,當編寫調用方法時,這樣的假設并無大礙。這時你完全能夠知道什么是參數的許可值,并按要求提供這些值。但如果你不對參數的數據進行檢驗,那么下列情況就會給你帶來很大麻煩:另外某個人創建了一個調用方法,但此人不知道允許的值;你在晚些時候添加了新的調用方法,并錯誤的傳遞了壞數據。

          3. 命名約定

          所有變量的定義應該遵循匈牙利命名法,它使用3字符前綴來表示數據類型,3個字符的前綴必須小寫,前綴后面是由表意性強的一個單詞或多個單詞組成的名字,而且每個單詞的首寫字母大寫,其它字母小寫,這樣保證了對變量名能夠進行正確的斷句。

          這樣,在一個變量名就可以反映出變量類型和變量所存儲的值的意義兩方面內容,這使得代碼語句可讀性強、更加容易理解。

          3.1     包、類及方法命名

          標示符類型

          命名約定

          例子

          l 全部小寫。

          l 標識符用點號分隔開來。為了使包的名字更易讀,Sun 公司建議包名中的標識符用點號來分隔。

          l Sun 公司的標準 java 分配包用標識符 .java 開頭。

          l全局包的名字用你的機構的 Internet 保留域名開頭。

          局部包

          interface.screens

          全局包

          com.rational.www.interface.screens

          類,接口

          l類的名字應該使用名詞。

          l每個單詞第一個字母應該大寫。

          l 避免使用單詞的縮寫,除非它的縮寫已經廣為人知,如HTTP

          Class Hello ;

          Class HelloWorld ;

          Interface Apple ;

          方法

          l第一個單詞一般是動詞。

          l 第一個字母是小些,但是中間單詞的第一個字母是大寫。

          l如果方法返回一個成員變量的值,方法名一般為get+成員變量名,如若返回的值是bool變量,一般以is作為前綴。

          l如果方法修改一個成員變量的值,方法名一般為:set + 成員變量名。

          getName();

          setName();

          isFirst();

          變量

          l第一個字母小寫,中間單詞的第一個字母大寫。

          l不要用_&作為第一個字母。

          l盡量使用短而且具有意義的單詞。

          l 單字符的變量名一般只用于生命期非常短暫的變量。i,j,k,m,n一般用于integers;c,d,e一般用于characters。

          l如果變量是集合,則變量名應用復數。

          l 命名組件采用匈牙利命名法,所有前綴均應遵循同一個組件名稱縮寫列表。

          String myName;

          int[] students;

           int i;

          int n;

          char c;

          btNew;

          (btButton的縮寫)

          常量

          l 所有常量名均全部大寫,單詞間以_隔開。

          int MAX_NUM;

           

          3.2     其它

          開發人員如果遇到上述表格中未列舉的類型,請書面通知相關管理人員,由管理人員集中更新列表內容,不得擅自啟用未經確定的新變量前綴。

          4. 使用常量

          4.1     使用常量

          1.       常數很容易在數據輸入時出錯

          常數存在的主要問題之一是你很容易在鍵入數字時出錯,從而顛倒了數字的位置。例如,當你鍵入數字10876時,很容易的鍵入1086718076。與處理變量和保留字的方法不同,編譯器并不在乎顛倒了位置和不正確的數字,有時簡單的錯誤造成的問題不會立即表現出來,而當問題表現出來時,它們會以隨機的計算錯誤的形式出現,這些錯誤很難準確定位。用常量來取代常數時,編譯器將在編譯時檢查常量的有效性。如果常量不存在,編譯器便將這一情況通知你,并拒絕進行編譯,這可以消除錯誤鍵入的數字帶來的問題,只要常量擁有正確的值,使用該常量的所有代碼也有使用該正確值。

          2.       常數很難不斷更新

          3.       常量使代碼更容易閱讀

          使用常量后,得到的一個額外好處是可使創建的代碼更容易閱讀。常數很不直觀。也許你對常數非常了解,但其他人則根本看不明白。通過合理的給常量命名,使用這些常量的代碼就變得比較直觀了,更容易閱讀。

          為常量賦予較寬的作用域,這與使用變量時的情況不同。在一個應用程序中你決不應該兩次創建相同的常量。如果你發現自己復制了一個常量,請將原始的常量說明轉至較寬的作用域,直到該常量可供引用它的所有方法為止。

          5. 變量

          5.1     定義有焦點的變量

          用于多個目的的變量稱為無焦點(多焦點)的變量。無焦點變量所代表的意義與程序的執行流程有關,當程序處于不同位置時,它所表示的意義是不固定的,這樣就給程序的可讀性和可維護性帶來了麻煩。

          5.2     只對常用變量名和長變量名進行縮寫

          如果需要對變量名進行縮寫時,一定要注意整個代碼中縮寫規則的一致性。例如,如果在代碼的某些區域中使用Cnt,而在另一些區域中又使用Count,就會給代碼增加不必要的復雜性。

          變量名中盡量不要出現縮寫。

          5.3     使用統一的量詞

          通過在結尾處放置一個量詞,就可創建更加統一的變量,它們更容易理解,也更容易搜索。例如,請使用strCustomerFirststrCustomerLast,而不要使用strFirstCustomerstrLastCustomer。

          量詞列表:

          量詞后綴

          說明

          First

          一組變量中的第一個

          Last

          一組變量中的最后一個

          Next

          一組變量中的下一個變量

          Prev

          一組變量中的上一個

          Cur

          一組變量中的當前變量

          5.4     使用肯定形式的布爾變量

          給布爾變量命名時,始終都要使用變量的肯定形式,以減少其它開發人員在理解布爾變量所代表的意義時的難度。

          5.5     為每個變量選擇最佳的數據類型

          這樣即能減少對內存的需求量,加快代碼的執行速度,又會降低出錯的可能性。用于變量的數據類型可能會影響該變量進行計算所產生的結果。在這種情況下,編譯器不會產生運行期錯誤,它只是迫使該值符合數據類型的要求。這類問題極難查找。

          5.6     盡量縮小變量的作用域

          如果變量的作用域大于它應有的范圍,變量可繼續存在,并且在不再需要該變量后的很長時間內仍然占用資源。

          它們的主要問題是,任何類中的任何方法都能對它們進行修改,并且很難跟蹤究竟是何處進行修改的。

          占用資源是作用域涉及的一個重要問題。對變量來說,盡量縮小作用域將會對應用程序的可靠性產生巨大的影響。

          6. 代碼的格式化

          6.1     對代碼進行格式化時,要達到的目的

          1.       通過代碼分割成功能塊和便于理解的代碼段,使代碼更容易閱讀和理解;

          2.       使用空行和注釋行,將程序中邏輯上不相關的代碼塊分開。比如:變量聲明部分和代碼語句間的分隔;較長的方法中,完成不同功能的代碼塊間的分隔。要避免出現邏輯上混亂的分隔,如:某一邏輯功能代碼塊中間用空行進行了分隔,但是在相鄰功能代碼塊之間卻沒有分隔,這樣會給程序閱讀者造成錯覺。

          3.       減少為理解代碼結構而需要做的工作;

          4.       使代碼的閱讀者不必進行假設;

          5.       使代碼結構盡可能做到格式清楚明了。

          6.2     編程原則

          1.       要將多個語句放在同一行上

          不論是變量聲明,還是語句都不要在一行上書寫多個。

          2.       縮進后續行

          當你將變量設置為某個值時,所有后續行的縮進位置應與第一行的變量值相同;

          當你調用一個方法時,后續行縮進到第一個參數的開始處;

          當你將變量或屬性設置為等于表達式的計算結果時,請從后面分割該語句,以確保該表達式盡可能放在同一行上。

          3.       if語句后縮進;

          else語句后縮進

          switch語句后縮進

          case語句后縮進

          do句后縮進

          已經用行接續符分割的語句的各個行要縮進

          對從屬于行標注的代碼進行縮進。

          4.       在執行統一任務的各個語句組之間插入一個空行。好的代碼應由按邏輯順序排列的進程或相關語句組構成。

          7. 代碼的注釋

          7.1     使用代碼注釋的目的

          1.       文字說明代碼的作用(即為什么要用編寫該代碼,而不是如何編寫);

          2.       確指出該代碼的編寫思路和邏輯方法;

          3.       人們注意到代碼中的重要轉折點;

          4.       使代碼的閱讀者不必在他們的頭腦中仿真運行代碼的執行方法.

          7.2     編程原則

          1.       用文字說明代碼的作用:

          簡單的重復代碼做寫什么,這樣的注釋幾乎不能給注釋增加什么信息.如果你使用好的命名方法來創建直觀明了的代碼那么這些類型的注釋絕對增加不了什么信息.

          2.       如果你想違背好的編程原則,請說明為什么

          有的時候你可能需要違背好的編程原則,或者使用了某些不正規的方法,.遇到這種情況時,請用內部注釋來說明你在做什么和為什么要這樣做。

          技巧性特別高的代碼段,一定要加詳細的注釋,不要讓其他開發人員花很長時間來研究一個高技巧但不易理解的程序段。

          3.       用注釋來說明何時可能出錯和為什么出錯

          4.       在編寫代碼前進行注釋

          給代碼加注釋的方法之一是在編寫一個方法前首先寫上注釋.如果你愿意,可以編寫完整句子的注釋或偽代碼.一旦你用注釋對代碼進行了概述,就可以在注釋之間編寫代碼.

          5.       在要注釋的代碼前書寫注釋

          注釋一定出現在要注釋的程序段前,不要在某段程序后書寫對這段程序的注釋,先看到注釋對程序的理解會有一定幫助。

          如果有可能,請在注釋行與上面代碼間加一空行。

          6.       純色字符注釋行只用于主要注釋

          注釋中要分隔時,請使用一行空注釋行來完成,不要使用純色字符,以保持版面的整潔、清晰。

          7.       避免形成注釋框

          用星號圍成的注釋框,右邊的星號看起來很好,但它們給注釋增加了任何信息嗎?實際上這會給編寫或編輯注釋的人增加許多工作。

          8.       增強注釋的可讀性

          注釋是供人閱讀的,而不是讓計算機閱讀的。

          1)    使用完整的語句。雖然不必將注釋分成段落(最好也不要分成段落),但你應盡量將注釋寫成完整的句子。

          2)    避免使用縮寫。縮寫常使注釋更難閱讀,人們常用不同的方法對相同的單詞進行縮寫,這會造成許多混亂,如果必須對詞匯縮寫,必須做到統一。

          3)    將整個單詞大寫,以突出它們的重要性。若要使人們注意注釋中的一個或多個單詞,請全部使用大寫字母。

          9.       對注釋進行縮進,使之與后隨的語句對齊。

          注釋通常位于它們要說明的代碼的前面。為了從視覺上突出注釋與它的代碼之間的關系,請將注釋縮進,使之與代碼處于同一個層次上。

          10.     為每個方法賦予一個注釋標頭

          每個方法都應有一個注釋標頭。方法的注釋標頭可包含多個文字項,比如輸入參數、返回值、原始作者、最后編輯該方法的程序員、上次修改日期、版權信息。

          11.     當行尾注釋用在上面這種代碼段結構中時,它們會使代碼更難閱讀。

          使用多個行尾注釋時(比如用于方法頂部的多個變量說明),應使它們互相對齊。這可使它們稍容易閱讀一些。

          12.     何時書寫注釋

          1)    請在每個if語句的前面加上注釋。

          2)    在每個switch語句的前面加上注釋。與if語句一樣,switch語句用于評估對程序執行產生影響的表達式。

          3)    在每個循環的前面加上注釋。每個循環都有它的作用,許多情況下這個作用不清楚直觀。

          7.3     注釋那些部分

          項目

          注釋哪些部分

          實參/

          參數

          參數類型

          參數用來做什么

          任何約束或前提條件

          示例

          字段/

          字段/屬性

          字段描述

          注釋所有使用的不變量

          示例

          并行事件

          可見性決策

          類的目的

          已知的問題

          類的開發/維護歷史

          注釋出采用的不變量

          并行策略

          編譯單元

          每一個類/類內定義的接口,含簡單的說明

          文件名和/或標識信息

          版權信息

          接口

          目的

          它應如何被使用以及如何不被使用

          局部變量

          用處/目的

          成員函數注釋

          成員函數做什么以及它為什么做這個

          哪些參數必須傳遞給一個成員函數

          成員函數返回什么

          已知的問題

          任何由某個成員函數拋出的異常

          可見性決策

          成員函數是如何改變對象的

          包含任何修改代碼的歷史

          如何在適當情況下調用成員函數的例子適用的前提條件和后置條件

          成員函數內部注釋

          控制結構

          代碼做了些什么以及為什么這樣做

          局部變量

          難或復雜的代碼

          處理順序

          7.4     示例

          7.4.1   塊注釋:

          主要用來描述文件,類,方法,算法等。一般用在文檔和方法的前面,也可以放在文檔的任何地方。以/*開頭,*/結尾。例:

          ……

          /*

          *     注釋

          */

          ……

          7.4.2   行注釋:

          主要用在方法內部,對代碼,變量,流程等進行說明。與塊注釋格式相似,但是整個注釋占據一行。例:

          ……

          /*    注釋       */

          ……

          7.4.3   尾隨注釋:

          與行注釋功能相似,放在代碼的同行,但是要與代碼之間有足夠的空間,便于分清。例:

          int m=4 ;        /*    注釋       */

          如果一個程序塊內有多個尾隨注釋,每個注釋的縮進應該保持一致。

          7.4.4   行尾注釋:

          與行注釋功能相似,放在每行的最后,或者占據一行。以//開頭。

          7.4.5   文檔注釋:

          與塊注釋相似,但是可以被javadoc處理,生成HTML文件。以/**開頭,*/結尾。文檔注釋不能放在方法或程序塊內。例:

          /**

                 注釋

          */

          8. 表達式和語句

          8.1     每行應該只有一條語句。

          8.2     if-else,if-elseif語句,任何情況下,都應該有{,}格式如下

          if (condition) {

                 statements;

          } else if (condition) {

              statements;

          } else{

              statements;

          }

          8.3     for語句格式如下

          for (initialization; condition; update) {

              statements;

          }

          如果語句為空

          for (initialization; condition; update) ;

          8.4     while語句格式如下

          while (condition) {

              statements;

          }

          如果語句為空:

                 while (condition);

          8.5     do-while語句格式如下

          do {

              statements;

          } while (condition);

          8.6        switch語句,每個switch里都應包含default子語句,格式如下

          switch (condition) {

          case ABC:

              statements;

              /* falls through */

          case DEF:

              statements;

              break;

          case XYZ:

              statements;

              break;

          default:

              statements;

              break;

          }

          8.7     try-catch語句格式如下

          try {

              statements;

          } catch (ExceptionClass e) {

              statements;

          } finally {

              statements;

          }

          9. 錯誤處理和異常事件

          通常的思想是只對錯誤采用異常處理邏輯和編程錯誤,設置錯誤,被破壞的數據資源耗盡,等等。

          通常的法則是系統在正常狀態下以及無重載和硬件失效狀態下,不應產生任何異常。異常處理時可以采用適當的日志機制來報告異常,包括異常發生的時刻。不要使用異常實現來控制程序流程結構。

          10.     封裝、事務

          1.       非商務公用組件單獨封裝

          2.       每一個業務流程單獨封裝

          3.       一次方法(組件)的調用應能完成某一項功能或流程,即符合完整性

          4.       一次方法(組件)的調用符合ACID事務性

          5.       多次方法(組件)的調用應包含在一個事務中

          11.     可移植性

          1.       盡量不要使用已經被標為不贊成使用的類或方法。

          2.       如果需要換行的話,盡量用 println 來代替在字符串中使用""n"。

          3.       separator()方法代替路徑中的”/””"”

          4.       pathSeptarator()方法代替路徑中的 ” : ” ” ;”



          JAVA規范
           
          設計類和方法 
          ==================
          創建具有很強內聚力的類 
          方法的重要性往往比類的重要性更容易理解,方法是指執行一個統一函數的一段代碼。類常被錯誤的視為是一個僅僅用于存放方法的容器。有些開發人員甚至把這種思路作了進一步的發揮,將他們的所有方法放入單個類之中。  之所以不能正確的認識類的功能,原因之一是類的實現實際上并不影響程序的執行。當一個工程被編譯時,如果所有方法都放在單個類中或者放在幾十個類中,這沒有任何關系。雖然類的數量對代碼的執行并無太大的影響,但是當創建便于調試和維護的代碼時,類的數量有時會帶來很大的影響。 
          類應該用來將相關的方法組織在一起。  當類包含一組緊密關聯的方法時,該類可以說具有強大的內聚力。當類包含許多互不相關的方法時,該類便具有較弱的內聚力。應該努力創建內聚力比較強的類。 大多數工程都包含許多并不十分適合與其他方法組合在一起的方法。在這種情況下,可以為這些不合群的方法創建一個綜合性收容類。 
          創建類時,應知道“模塊化”這個術語的含義是什么。類的基本目的是創建相當獨立的程序單元。 
          創建松散連接和高度專用的方法 
          1) 所有方法都執行專門的任務 
          每個方法都應執行一項特定的任務,它應出色的完成這項任務。應避免創建執行許多不同任務的方法。  創建專用方法有許多好處。首先調試將變得更加容易。 
           2) 盡量使方法成為自成一體的獨立方法 
          當一個方法依賴于其他方法的調用時,稱為與其他方法緊密連接的方法。緊密連接的方法會使調試和修改變得比較困難,因為它牽涉到更多的因素。松散連接的方法優于緊密連接的方法,但你不可能使每個方法都成為獨立的方法。 
          若要使方法具備較強的獨立性,方法之一是盡量減少類變量。  創建方法時,設法將每個方法視為一個黑箱,其他例程不應要求了解該方法的內部工作情況,該方法也不應要求了解它外面的工程情況。這就是為什么你的方法應依靠參數而不應依靠全局變量的原因。 
          3) 創建專用方法時,請考慮下列指導原則: 
          (1) 將復雜進程放入專用方法。如果應用程序使用復雜的數學公式,請考慮將每個公式放入它自己的方法中。這樣使用這些公式的其他方法就不包含用于該公式的實際代碼。這樣也可以更容易發現與公式相關的問題。 
          (2) 將數據輸入/輸出(I/O)放入專用方法。 
          (3) 將專用方法中可能要修改的代碼隔離。如果你知道某個進程經常變更,請將這個多變的代碼放入專用方法,以便以后可以更容易的進行修改,并減少無意中給其他進程帶來問題的可能性。 
          (4) 將業務規則封裝在專用方法中。業務規則常屬于要修改的代碼類別,應與應用程序的其余部分隔開。其他方法不應知道業務規則,只有要調用的方法才使用這些規則。 
          4) 設計類和方法時,要達到下列目的: 
          1) 創建更加容易調試和維護的方法 
          2) 創建具有強大內聚力的類 
          3) 創建高度專用的方法 
          4) 創建松散連接的方法 
          5) 盡量使方法具有獨立性 
          6) 提高方法的扇入性 
          7) 降低方法的扇出性 
           
           
           
          編程原則 
          ==================
          為方法和類賦予表義性強的名字 
          為了使代碼更加容易理解,最容易的方法之一是為你的方法賦予表義性強的名字。函數名DoItGetIt的可讀性很難與CalculateSalesTax、 RetrieveUserID相比。  由縮寫方法名組成的代碼很難理解和維護,沒有理由再這樣做了。  給方法正確的命名,可使程序工程的調試和維護工作大大的改觀。請認真對待方法命名的工作,不要為了減少鍵入操作量而降低方法的可理解度。  實際應用舉例: 
          1) 給方法命名時應大小寫字母混合使用。如果句子全使用大寫字母,那么閱讀起來就非常困難,而大小寫字母混合使用的句子,閱讀起來就很容易。 
          2) 定義方法名時不要使用縮寫。如果你認為應用程序中的某些工程應使用縮寫,那么請將這些情況加上注釋,并確保每個人在所有時間內都使用這些縮寫。決不要在某些方法中對某些單詞進行縮寫,而在別的方法中卻不使用縮寫。 
          為每個方法賦予單個退出點 
          創建方法時,始終都應顯式地定義它的作用域
          1) 如果你真的想創建一個公用方法,請向代碼閱讀者說明這一點。 
          2) 通過為每個方法賦予一個明確定義的作用域,可以減少代碼閱讀者需要投入的工作量。應確保你為方法賦予最有意義的作用域。如果一個方法只被同一類中的另一個方法調用,那么請將它創建成私有方法。如果該方法是從多個類中的多個方法中調用,請將該說明為公用方法。 
          用參數在方法之間傳遞數據 
          應盡量避免使用類變量。一般來說,變量的作用域越小越好。為了減少類變量,方法之一是將數據作為參數在不同方法之間傳遞,而不是讓方法共享類變量。 
          1) 為每個參數指定數據類型。 
          2) 始終要對數進行檢驗,決不要假設你得數據沒有問題。程序員常犯的一個錯誤是在編寫方法時假設數據沒有問題。在初始編程階段,當編寫調用方法時,這樣的假設并無大礙。這時你完全能夠知道什么是參數的許可值,并按要求提供這些值。但如果你不對參數的數據進行檢驗,那么下列情況就會給你帶來很大麻煩:另外某個人創建了一個調用方法,但此人不知道允許的值;你在晚些時候添加了新的調用方法,并錯誤的傳遞了壞數據。 
           
           

          命名約定 
          ==================
          變量的定義
          變量的定義應該遵循匈牙利命名法,它使用3字符前綴來表示數據類型,3個字符的前綴必須小寫,前綴后面是由表意性強的一個單詞或多個單詞組成的名字,而且每個單詞的首寫字母大寫,其它字母小寫,這樣保證了對變量名能夠進行正確的斷句。  這樣,在一個變量名就可以反映出變量類型和變量所存儲的值的意義兩方面內容,這使得代碼語句可讀性強、更加容易理解。
          包、類及方法命名 
          1)  
           全部小寫。  標識符用點號分隔開來。為了使包的名字更易讀,Sun 公司建議包名中的標識符用點號來分隔。 
           Sun 公司的標準 java 分配包用標識符 .java 開頭。 
           全局包的名字用你的機構的 Internet 保留域名開頭 。 
          局部包:  interface.screens 
          全局包:  com.rational.www. interface.screens 
          2) 類,接口 
          類的名字應該使用名詞。 
           每個單詞第一個字母應該大寫。 
          避免使用單詞的縮寫,除非它的縮寫已經廣為人知,如HTTP。 
          Class Hello ; 
          Class HelloWorld ; 
          Interface Apple ; 
          3) 方法 
          第一個單詞一般是動詞。 
          第一個字母是小些,但是中間單詞的第一個字母是大寫。 
          如果方法返回一個成員變量的值,方法名一般為get+成員變量名,如若返回的值是bool變量,一般以is作為前綴。 
           如果方法修改一個成員變量的值,方法名一般為:set + 成員變量名。 
          getName();  setName();  isFirst(); 
          4) 變量 
          第一個字母小寫,中間單詞的第一個字母大寫。 
          不要用_&作為第一個字母。 
          盡量使用短而且具有意義的單詞。 
          單字符的變量名一般只用于生命期非常短暫的變量。i,j,k,m,n一般用于integers;c,d,e一般用于characters。 
          如果變量是集合,則變量名應用復數。 
          命名組件采用匈牙利命名法,所有前綴均應遵循同一個組件名稱縮寫列表。 
          String myName;  int[] students;  int i;  int n;  char c;  btNew;  (btButton的縮寫
          5) 常量 
          所有常量名均全部大寫,單詞間以‘_’隔開。  int MAX_NUM; 
          6) 其它 
          開發人員如果遇到上述表格中未列舉的類型,請書面通知相關管理人員,由管理人員集中更新列表內容,不得擅自啟用未經確定的新變量前綴。 
           
           
           
           
          MVC規范 
          ==================
                        分層
          MVC的設計模式中,要求在Application開發中你把商業邏輯,界面顯示,數據分離。也就是分別在Model,View,Controller實現:數據,控制(商業邏輯)顯示(頁面顯示)。
                        規則
                                      1) 用戶的所有請求統一由控制器截獲
                                      2) 控制器根據請求種類,調用不同的業務對象(業務bean),根據業務對象的返回值,來決定該把哪個頁面相應給用戶
                                      3) jsp中,不會出現任何業務代碼/數據庫操作??梢杂袑嵗?/span>bean的操作,或者從session、數據bean中取得數據
          4) 在作為控制器的servlet中不會出現網頁內容、業務代碼、數據庫操作??梢杂薪邮?/span>request值、實例化bean、調用bean的方法、頁面轉移
          5) 數據bean對應數據庫中某張表里的一條記錄,這張表中的所有列都應該成為數據bean的私有屬性
          6) 業務beanController(servlet)中實例化
          7) 數據bean在業務beanController中實例化
           
           
           
          其它規范 
          ==================
          Java文件樣式
                               所有的 Java(*.java) 文件都必須遵守如下的樣式規則
                                             1) 版權信息
                                                           版權信息必須在 java 文件的開頭,比如:
                                                           /**
                                                           * Copyright &reg; 2000 Shanghai XXX Co. Ltd.
                                                           * All right reserved.
                                                           */
                                                           其他不需要出現在 javadoc 的信息也可以包含在這里。
                                             2) Package/Imports
          package 行要在 import 行之前,import 中標準的包名要在本地的包名之前,而且按照字母順序排列。如果 import 行中包含了同一個包中的不同子目錄,則應該用 * 來處理。
                                                           package hotlava.net.stats;
                                                           import java.io.*;
                                                           import java.util.Observable;
                                                           import hotlava.util.Application;
                                                           這里 java.io.* 使用來代替InputStream and OutputStream 的。
                                             3) Class
                                                           (1) 類的注釋
          接下來的是類的注釋,一般是用來解釋類的。
                                                                         /**
                                                                        * A class representing a set of packet and byte counters
                                                                        * It is observable to allow it to be watched, but only
                                                                        * reports changes when the current set is complete
                                                                         */
                                                           (2) 類定義
                                                                  (3) 類的成員變量
                                                                         接下來是類的成員變量:
                                                                         /**
                                                                         * Packet counters
                                                                         */
                                                                         protected int[] packets;
                                                                         public 的成員變量必須生成文檔(JavaDoc)。
          proceted、private package 定義的成員變量如果名字含義明確的話,可以沒有注釋。
                                                                  (4) 構造函數
                                                                         接下來是構造函數,它應該用遞增的方式寫(比如:參數多的寫在后面)
                                                           (5) 類方法
                                                                         下面開始寫類的方法:
                                                                         /**
                                                                          * Set the packet counters
                                                                          * (such as when restoring from a database)
                                                                         */
                                                                         protected final
                                                                                    void setArray(int[] r1, int[] r2, int[] r3, int[] r4)
                                                                                    throws IllegalArgumentException
                                                                                    {
                                                                                                  //
                                                                                                  // Ensure the arrays are of equal size
                                                                                                  //
                                                                                                  if (r1.length != r2.length || r1.length != r3.length || r1.length != r4.length)
                                                                                       throw new IllegalArgumentException("Arrays must be of the same size");
                                                                                       System.arraycopy(r1, 0, r3, 0, r1.length);
                                                                                       System.arraycopy(r2, 0, r4, 0, r1.length);
                                                                         }
          數組的命名
                               數組應該總是用下面的方式來命名:
                                             byte[] buffer;
                               而不是:
                                             byte buffer[];
          垃圾收集
          JAVA使用成熟的后臺垃圾收集技術來代替引用計數。但是這樣會導致一個問題:你必須在使用完對象的實例以后進行清場工作。比如一個prel的程序員可能這么寫:
                               .{
                                             FileOutputStream fos = new FileOutputStream(projectFile);
                                             project.save(fos, "IDE Project File");
                               }
                               ...
                               除非輸出流一出作用域就關閉,非引用計數的程序語言,比如JAVA,是不能自動完成變量的清場工作的。必須象下面一樣寫:
                               FileOutputStream fos = new FileOutputStream(projectFile);
                                   project.save(fos, "IDE Project File");
                               fos.close();
          性能
          在寫代碼的時候,從頭至尾都應該考慮性能問題。這不是說時間都應該浪費在優化代碼上,而是我們時刻應該提醒自己要注意代碼的效率。比如:如果沒有時間來實現一個高效的算法,那么我們應該在文檔中記錄下來,以便在以后有空的時候再來實現她。不是所有的人都同意在寫代碼的時候應該優化性能這個觀點的,他們認為性能優化的問題應該在項目的后期再去考慮,也就是在程序的輪廓已經實現了以后。
                               1) 使用 StringBuffer 對象
          在處理 String 的時候要盡量使用 StringBuffer 類,StringBuffer 類是構成 String 類的基礎。String 類將 StringBuffer 類封裝了起來,(以花費更多時間為代價)為開發人員提供了一個安全的接口。當我們在構造字符串的時候,我們應該用 StringBuffer 來實現大部分的工作,當工作完成后將 StringBuffer 對象再轉換為需要的 String 對象。比如:如果有一個字符串必須不斷地在其后添加許多字符來完成構造,那么我們應該使用 StringBuffer 對象和她的 append() 方法。如果我們用String 對象代替 StringBuffer 對象的話,會花費許多不必要的創建和釋放對象的 CPU 時間。
                               2) 避免太多的使用 synchronized 關鍵字
                              避免不必要的使用關鍵字 synchronized,應該在必要的時候再使用她,這是一個避免死鎖的好方法。
           
           
           
          資料
          1:了解MVC
          MVC
          Model,View,Controller的縮寫,MVCApplication開發的設計模式,也就是大家所知道的Model2.MVC的設計模式中,要求在Application開發中你把商業邏輯,界面顯示,數據分離。也就是分別在Model,View,Controller實現:數據,控制(商業邏輯)顯示(頁面顯示).在以前或者說傳統的Web Application開發方式當中,如Asp,Php,Jsp(Model 1)開發當中我們在Asp(Php,Jsp)中實現一切,如:從數據庫中取到我們需要的數據,并根據數據之間的關聯和實際的需要按照某種方式把他顯示在頁面中以及從頁面提交的表單中提取數據,根據商業邏輯從數據庫查詢相關數據,或者把數據寫入數據庫。也就是說我們在Asp(Php,Jsp)實現一切包括:界面顯示,商業邏輯,數據存取。這樣帶來的后果就是你所寫的Asp(Php,Jsp)
          沒有層次,并且HtmlScript(JavaScriptJScript,AspPhp、Jsp源代碼)相互嵌套.可維護性差,最要命的是在Web Application通常顯示一塊是由美工完成的,很多時候也是你先寫好Asp、PhpJsp然后美工進行美化,很有可能你發現經過美工處理完以后你的代碼已經面目全非了。你不得不把你的代碼重新組織。在MVC模式中這個問題的解決辦法是:View中負責顯示,View一般從Controller得到已經處理過的數據,然后顯示在頁面當中,應該說這樣在Html中嵌套很少的Script.基本上美工的修改不大會廢掉你的勞動成果。
          2: MVC模式的好處
          1)
          各施其職,互不干涉
          MVC模式中,三個層各施其職,所以如果一旦哪一層的需求發生了變化,就只需要更改相應的層中的代碼而不會影響到其它層中的代碼。假如業務發生了變化,如在取文章時可能webmaster把一些文章作了無效標志,不能直接把所有文章取出來,只能取出有效的文章,這時業務就發生了改變。再設想一下,如果這個業務邏輯在100個頁面中都要用到,那么MVC模式就體現了它的靈活性。我們可以不更改任何JSP,只要更改model層中的相應類中的SQL語句即可。
          2) 有利于開發中的分工
          MVC模式中,由于按層把系統開,那么就能更好的實現開發中的分工。網頁設計人員可以進行開發視圖層中的JSP,對業務熟悉的開發人員可開發業務層,而其它開發人員可開發控制層。
          3) 有利于組件的重用
          分層后更有利于組件的重用。如控制層可獨立成一個能用的組件,視力層也可做成通用的操作界面。

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


          網站導航:
           
          主站蜘蛛池模板: 武隆县| 东山县| 常山县| 桃园县| 嘉黎县| 河西区| 岳池县| 都兰县| 明水县| 嵊州市| 贵定县| 历史| 靖远县| 武宁县| 方正县| 鄂托克前旗| 公安县| 上饶市| 南宫市| 赫章县| 淮北市| 辛集市| 桐梓县| 双辽市| 罗城| 惠安县| 临夏市| 安仁县| 廊坊市| 兴安县| 苏尼特右旗| 江油市| 清徐县| 诏安县| 湛江市| 德阳市| 青海省| 米泉市| 车险| 顺平县| 务川|