Java交流空間

          共同夢想,一起飛翔,明天更美好!

           

          java編程規范(學java的第一步)

           

          1         Java編程規范

          1.1     命名約定

          1.1.1    包的命名

          JDK 的標準是——包名稱的所有字母均小寫,如:

          package myownpackage;

          1.1.2    類的命名

          JDK 的標準是——大寫一個類名的首字母,若類名由幾個單詞構成,那么把它們緊靠到一起(也就是說,不要用下劃線來分隔名字)。此外,每個嵌入單詞的首字母都要采用大寫形式。類名稱應該是一個名詞短語。如:

          class ZipFileAccesser

          1.1.3    變量的命名

          1.        ?變量命名一般原則(參照匈牙利命名法)(必須)
          2.        能清楚表示變量的類型
          3.        能簡明表達變量的涵義
          4.        ?常量的命名(必須)
          5.        常量名稱全部大寫,如:

          public final int PORT = 2000;

          6.        主要基本類型變量的命名

          主要類型名稱縮寫格式及規則:由類型全稱取一個字母組成 + 實際名稱,如:

          String strTemp;

          對幾種主要的基本類型變量命名前綴的規定(參見附錄A:基本命名參考

          7.        靜態變量的命名

          靜態變量名稱以字符串“STATIC”開頭,如:

          static int STATICintNumber;

          8.        臨時變量的命名(推薦)

          臨時性變量格式為(類型名稱縮寫 + Temp),如:

          String strTemp=”asdf”;

          9.        對象命名規則:

          第一原則:當類名是由多單詞組成,取每個單詞的首字母,將其小寫形式組合而成變量名稱的前綴,當對象是由單個單詞組成時,取整個單詞的小寫形成作為變量名的前綴,如:

          PrintWriter pwTemp;

          Socket socketTemp;

          第二原則:如果這樣命名時產生了重復現象,則和類型名稱縮寫提取原則類似,取三個小寫輔音字母或習慣性的用法,總之以能明顯區別類名稱為原則。如:ServletResponse ServletRequest 如果按照第一原則,兩個對象都可命名為srTemp,產生了重復,此時就應按照第二原則,命名為srpTemp srqTemp

          10.     成員變量的命名

          成員變量的命名原則與臨時變量相同,但在可能與臨時變量名稱重復的調用場合,應加上this.以示區別。推薦:對大多數成員變量調用的場合加上this.以利區別,如:

          public String strUserName;

          this.strUserName = strUserName;

          1.1.4    方法的命名

          方法名的第一個字母采用小寫,其他嵌入單詞首字母大寫。方法名應該是一個動賓結構的短語,能夠簡明恰當的表達出方法完成的操作。如:

          public String getStudentName(…);

          1.1.5    其它說明:(推薦)

          一般不允許使用數字和下劃線。如:

          socket1,socket_num;

          1.2     注釋

          注釋采用javadoc的注釋方法,所有注釋放置于所注釋目標的上方。

          1.2.1    /接口的頭注釋

          /**********************************************************

          * 類描述信息

          * @author 作者信息

          * @version 版本信息,時間

          * @since 創自信息

          **********************************************************/

          1.2.2    屬性的注釋

          /**

          * 注釋內容

          */

          1.2.3    方法的頭注釋

          /**

          * @param

          * @return

          * @throws

          */

          注:每個參數名后必須有相應的說明,格式如下

          [參數名 參數說明]

          如:

          * @param intCounter 計數器

          * @param strName 變量名稱

          * @param blnFlag 標志位

          返回值不必寫類型,如果沒有返回值或者返回值是void 就不寫@return,如:

          * @return 當前的計數值

          異常要逐個分行寫出,如:

          * @throws IOException 如果發生I/O 錯誤

          * @throws ZIPException 如果發生ZIP 文件錯誤

          1.2.4    代碼內的注釋

          直接在代碼內出現的注釋通常使得代碼易于理解。通過在前面加上一個空行和一個注釋行(或更多行)來概括大的操作。在需要時用每行后面的注釋或者更多的注釋來解釋較奇特的代碼。不止一行的注釋通常用/*…*/,而不是//,但//在行尾注釋中更好用。單行的注釋用兩種方法都可以,但推薦使用//

          1.2.5    未完成代碼的提醒注釋

          /**

          * @todo   注釋內容

          */

          1.3     代碼分隔

          import …

          空一行

          package …

          空一行

          class …

          1.        屬性與屬性間空一行,方法與方法之間空一行,類與類之間空一行。先寫公有屬性,后寫保護屬性,最后寫私有屬性。
          2.        在方法內部,幾行關系緊密的代碼之間應該不空行,但兩個相對獨立的代碼塊之間應空一行。一般,在方法內部每隔35 行就應有一個空行。兩個相鄰空行之間的一段代碼為一個代碼塊,
          3.        每隔代碼塊前面應有行注釋。
          4.        構造子必須放在其他所有方法前
          5.        運算符兩邊要加一個空格,如:

          intTotal = intAvg * intNum;

          6.        括號兩邊內側要各加一個空格,如:

          void main ( String[ ] args );

          7.        一行代碼只允許有一條語句,但這樣簡單的形式除外:

          int ix, iy;

          8.        減少public 域的定義,盡量通過方法而不是通過對象的實例直接訪問對象的域,并且所有的成員域必須加以說明。如:

          String strUserName; //用戶名稱

          1.4     代碼縮進原則

          1.        類名、類體、方法體依次縮進一個單位長
          2.        一個單位長是四個空格(可設為一個TAB 長)

          1.5     雜項格式化約定

          1.        在代碼塊之間使用空行,通過概括注釋來分隔。
          2.        使行的長度限制在80個字符內。
          3.        tab來縮進、每個tab長度為4個空格。
          4.        左花括號與方法名處同一行,間隔一個空格。
          5.        跳轉語句的標號與switch關鍵字對齊。
          6.        像在英文中那樣使用空格(關鍵字和逗號后面加,括號后面不加,許多操作符之間加)。

          2         附錄A:基本命名參考

          2.1     構造名稱

          w           一般的匈牙利名稱是由三部分組成:一個或多個前綴,一個基本標簽和一個qualifier

          w           基本標簽表示了變量的類型(例如,“co”表示一種顏色)。

          w           前綴修飾這個類型(例如,“rg”表示體格數組,所以“rgco”表示一個顏色數組)。

          w           qualifier描述了這種特定類型的具體用途(例如,“rgcoGray”表示一個作為灰色使用的顏色數組)。

          2.2     標準基本標簽

          i

          int

          f

          float

          d

          double

          b

          boolean

          ch

          char

          str

          字符串String

          bt

          byte類型。

          l

          long類型 (有符號32位的值)

          date

          日期型

          enum

          枚舉型

          2.3     標準前綴

          rg/a

          數組(來自于“range”)。例如,“rgch”表示一個字符數組。

          c

          某個基類條目的計數。例如,“cch”表示字符的計數。

          d

          某種基類的值之間的差值或delta。例如,“dx”表示兩個x類型的值之間的差值。

          此外,以下是我們在合適的時候可以在任何匈牙利前綴之前加入的特殊前綴:

          m_

          C++類的數據成員。

          s_

          C++類的靜態數據成員。

          2.4     標準qualifier

          First

          某集合中的第一個條目,或所關心的第一個條目(例如pchFirst)。

          Last

          某集合的最后一個條目,或所關心的最后一個條目(例如,pchLast)。當作為下標使用時,Last表示最后一個有效的/希望的值,所以一個循環可能是:
          for (ich = ichFirst; ich <= ichLast; ich++)

          Lim

          某集合的元素個數上限。與Last不同,Lim不代表一個有效的值,Lim代表最后一個有效值后面的一個,所以一個循環可能是:

          for (ich = ichFirst; ich < ichLim; ich++)

          Min

          某集合的最小元素。與First相似,但通常表示第一個有效的值,而不是要處理的第一個值。

          Max

          某集合的元素個數上限(Lim相同)。不幸的是,標準的英文中的“Max”通常表示最后一個有效的值,但Max qualifier不是一個有效的值,它是最后一個有效值后面的一個。和Lim一樣,典型的用法應該是:

          for (ich = ichMin; ich < ichMax; ich++)
          對此要特別小心。

          Mac

          Max相似,但有時可用在“當前”最大值可能隨時間變化的情況下。注意Mac也是代表“最后的”有效值之后的一個。

          Mic

          Min相似,但有時可用在“當前”最大值可能隨時間變化的情況下。

          T

          臨時的值。這個qualifier可能會被過度使用,而不能為某些量起一個好名字,但有時少數的臨時值是可以的,比如在一個典型的交換操作中。

          TT, T3, etc.

          這是在需要更確切的名字的時候對T的進一步濫用。這些用法應當被避免。

          Sav

          用于保存一個值的臨時量,使該值可以在以后被恢復。例如:hwndSav = hwnd; ...; hwnd = hwndSav;

          Null

          特殊的0值,總是等價于0,但用于特定的目的(例如 hwndNull)

          Nil

          特殊的無效值,不一定與0等價(可能是-1,或任何其它值)。為避免混淆,最好對同一類型避免既使用Null又使用Nil

          Src

          某項操作的源,典型的用法是與表示目標的Dest匹配使用,如下:

          *pchDest = *pchSrc

          Dest

          目標。參見Src

          Sum

          總和。

          3         附錄B:標準代碼樣本

          import com.sun.tools.doclets.*;

          import com.sun.javadoc.*;

          import java.io.*;

          import java.lang.*;

          import java.util.*;

          /***********************************************************************

           * Generate the package index page "overview-summary.html" for the right-hand

           * frame. A click on the package name on this page will update the same frame

           * with the "pacakge-summary.html" file for the clicked package.

           *

           * @author Atul M Dambalkar

           * @version 1.0

           * @since JDK 1.4

           ***********************************************************************/

          public class PackageIndexWriter

              extends AbstractPackageIndexWriter {

              /**

               * Root of the program structure. Used for "overview" documentation.

               */

              private RootDoc root;

              /**

               * Map representing the group of packages as specified on the command line.

               *

               * @see Group

               */

              private Map groupPackageMap;

              /**

               * List to store the order groups as specified on the command line.

               */

              private List groupList;

              /**

               * Construct the PackageIndexWriter. Also constructs the grouping

               * information as provided on the command line by "-group" option. Stores

               * the order of groups specified by the user.

               *

               * @see Group

               */

              public PackageIndexWriter(String filename, RootDoc root) throws IOException {

                  super(filename);

                  this.root = root;

                  groupPackageMap = Group.groupPackages(packages);

                  groupList = Group.getGroupList();

              }

              /**

               * Generate the package index page for the right-hand frame.

               *

               * @param root the root of the doc tree.

               */

              public static void generate(RootDoc root) throws DocletAbortException {

                  PackageIndexWriter packgen;

                  String filename = "overview-summary.html";

                  try {

                      packgen = new PackageIndexWriter(filename, root);

                      packgen.generatePackageIndexFile();

                      packgen.close();

                  }

                  catch (IOException exc) {

                      Standard.configuration().standardmessage.error(

                          "doclet.exception_encountered",

                          exc.toString(), filename);

                      throw new DocletAbortException();

                  }

              }

              /**

               * Print each package in separate rows in the index table. Generate link

               * to each package.

               *

               * @param packagedoc Package to which link is to be generated.

               */

              protected void printIndexRow(PackageDoc packagedoc) {

                  trBgcolorStyle("white", "TableRowColor");

                  summaryRow(20);

                  bold();

                  printPackageLink(packagedoc);

                  boldEnd();

                  summaryRowEnd();

                  summaryRow(0);

                  printSummaryComment(packagedoc);

                  summaryRowEnd();

                  trEnd();

              }

              /**

               * Depending upon the grouping information and their titles, generate

               * separate table indices for each package group.

               */

              protected void generateIndex() {

                  for (int i = 0; i < groupList.size(); i++) {

                      String groupname = (String) groupList.get(i);

                      List list = (List) groupPackageMap.get(groupname);

                      if (list != null && list.size() > 0) {

                          printIndexContents( (PackageDoc[]) list.

                                             toArray(new PackageDoc[list.size()]),

                                             groupname);

                      }

                  }

              }

              /**

               * Print the overview summary comment for this documentation. Print one line

               * summary at the top of the page and generate a link to the description,

               * which is generated at the end of this page.

               */

              protected void printOverviewHeader() {

                  if (root.inlineTags().length > 0) {

                      printSummaryComment(root);

                      p();

                      bold(getText("doclet.See"));

                      br();

                      printNbsps();

                      printHyperLink("", "overview_description",

                                     getText("doclet.Description"), true);

                      p();

                  }

              }

              /**

               * Print Html tags for the table for this package index.

               */

              protected void printIndexHeader(String text) {

                  tableIndexSummary();

                  tableHeaderStart("#CCCCFF");

                  bold(text);

                  tableHeaderEnd();

              }

              /**

               * Print Html closing tags for the table for this package index.

               */

              protected void printIndexFooter() {

                  tableEnd();

                  p();

                  space();

              }

              /**

               * Print the overview comment as provided in the file specified by the

               * "-overview" option on the command line.

               */

              protected void printOverviewComment() {

                  if (root.inlineTags().length > 0) {

                      anchor("overview_description");

                      p();

                      printInlineComment(root);

                      p();

                  }

              }

              /**

               * Call {@link #printOverviewComment()} and then genrate the tag information

               * as provided in the file specified by the "-overview" option on the

               * command line.

               */

              protected void printOverview() throws IOException {

                  printOverviewComment();

                  generateTagInfo(root, null); //new

              }

              /**

               * Print the header for navigation bar. Also print the "-title" specified

               * on command line, at the top of page.

               */

              protected void printNavigationBarHeader() {

                  navLinks(true);

                  hr();

                  printConfigurationTitle();

              }

              /**

               * Print the footer fornavigation bar. Also print the "-bottom" specified

               * on command line, at the top of page.

               */

              protected void printNavigationBarFooter() {

                  hr();

                  navLinks(false);

                  printBottom();

              }

          }

          4         附錄C:更多Java編程規則

          選自《Think in java》,包含了大量有用的建議,幫助大家進行低級程序設計,并提供了代碼編寫的一般性指導:

          1.        類名首字母應該大寫。字段、方法以及對象的首字母應小寫。對于所有標識符,其中包含的所有單詞都應緊靠在一起,而且大寫中間單詞的首字母。例如:

          ThisIsAClassName

          thisIsMethodOrFieldName

          若在定義中出現了常數初始化字符,則大寫static final基本類型標識符中的所有字母。這樣便可標志出它們屬于編譯期的常數。

          Java包(Package)屬于一種特殊情況:它們全都是小寫字母,即便中間的單詞亦是如此。對于域名擴展名稱,如comorgnet或者edu等,全部都應小寫(這也是Java 1.1Java 1.2的區別之一)。

          2.        為了常規用途而創建一個類時,請采取“經典形式”,并包含對下述元素的定義:

          equals()

          hashCode()

          toString()

          clone()implement Cloneable

          implement Serializable

          3.        對于自己創建的每一個類,都考慮置入一個main(),其中包含了用于測試那個類的代碼。為使用一個項目中的類,我們沒必要刪除測試代碼。若進行了任何形式的改動,可方便地返回測試。這些代碼也可作為如何使用類的一個示例使用。
          4.        應將方法設計成簡要的、功能性單元,用它描述和實現一個不連續的類接口部分。理想情況下,方法應簡明扼要。若長度很大,可考慮通過某種方式將其分割成較短的幾個方法。這樣做也便于類內代碼的重復使用(有些時候,方法必須非常大,但它們仍應只做同樣的一件事情)。
          5.        設計一個類時,請設身處地為客戶程序員考慮一下(類的使用方法應該是非常明確的)。然后,再設身處地為管理代碼的人考慮一下(預計有可能進行哪些形式的修改,想想用什么方法可把它們變得更簡單)。
          6.        使類盡可能短小精悍,而且只解決一個特定的問題。下面是對類設計的一些建議:
          (1)     數量眾多的方法涉及到類型差別極大的操作:考慮用幾個類來分別實現
          (2)     許多成員變量在特征上有很大的差別:考慮使用幾個類
          7.        讓一切東西都盡可能地“私有”——private。在多線程環境中,隱私是特別重要的一個因素——只有private字段才能在非同步使用的情況下受到保護。
          8.        謹惕“巨大對象綜合癥”。對一些習慣于順序編程思維、且初涉OOP領域的新手,往往喜歡先寫一個順序執行的程序,再把它嵌入一個或兩個巨大的對象里。根據編程原理,對象表達的應該是應用程序的概念,而非應用程序本身。
          9.        若不得已進行一些不太雅觀的編程,至少應該把那些代碼置于一個類的內部。
          10.     任何時候只要發現類與類之間結合得非常緊密,就需要考慮是否采用內部類,從而改善編碼及維護工作。
          11.     盡可能細致地加上注釋,并用javadoc注釋文檔語法生成自己的程序文檔。
          12.     避免使用“魔術數字”,這些數字很難與代碼很好地配合。如以后需要修改它,無疑會成為一場噩夢,因為根本不知道“100”到底是指“數組大小”還是“其他全然不同的東西”。所以,我們應創建一個常數,并為其使用具有說服力的描述性名稱,并在整個程序中都采用常數標識符。這樣可使程序更易理解以及更易維護。
          13.     當客戶程序員用完對象以后,若你的類要求進行任何清除工作,可考慮將清除代碼置于一個良好定義的方法里,采用類似于cleanup()這樣的名字,明確表明自己的用途。除此以外,可在類內放置一個boolean(布爾)標記,指出對象是否已被清除。在類的finalize()方法里,請確定對象已被清除。在采取象這樣的方案之前,請確定finalize()能夠在自己的系統中工作(可能需要調用System.runFinalizersOnExit(true),從而確保這一行為)。
          14.     在一個特定的作用域內,若一個對象必須清除(非由垃圾收集機制處理),請采用下述方法:初始化對象;若成功,則立即進入一個含有finally從句的try塊,開始清除工作。
          15.     若在初始化過程中需要覆蓋(取消)finalize(),請記住調用super.finalize()(若Object屬于我們的直接超類,則無此必要)。在對finalize()進行覆蓋的過程中,對super.finalize()的調用應屬于最后一個行動,而不應是第一個行動,這樣可確保在需要基礎類組件的時候它們依然有效。
          16.     創建大小固定的對象集合時,請將它們傳輸至一個數組(若準備從一個方法里返回這個集合,更應如此操作)。這樣一來,我們就可享受到數組在編譯期進行類型檢查的好處。
          17.     盡量使用interfaces,不要使用abstract類。若已知某樣東西準備成為一個基礎類,那么第一個選擇應是將其變成一個interface(接口)。只有在不得不使用方法定義或者成員變量的時候,才需要將其變成一個abstract(抽象)類。接口主要描述了客戶希望做什么事情,而一個類則致力于(或允許)具體的實施細節。
          18.     在構建函數內部,只進行那些將對象設為正確狀態所需的工作。盡可能地避免調用其他方法,因為那些方法可能被其他人覆蓋或取消,從而在構建過程中產生不可預知的結果。
          19.     對象不應只是簡單地容納一些數據;它們的行為也應得到良好的定義。
          20.     警惕“過早優化”。首先讓它運行起來,再考慮變得更快——但只有在自己必須這樣做、而且經證實在某部分代碼中的確存在一個性能瓶頸的時候,才應進行優化。除非用專門的工具分析瓶頸,否則很有可能是在浪費自己的時間。性能提升的隱含代價是自己的代碼變得難于理解,而且難于維護。
          21.     請記住,閱讀代碼的時間比寫代碼的時間多得多。思路清晰的設計可獲得易于理解的程序,但注釋、細致的解釋以及一些示例往往具有不可估量的價值。無論對你自己,還是對后來的人,它們都是相當重要的。如對此仍有懷疑,那么請試想自己試圖從聯機Java文檔里找出有用信息時碰到的挫折,這樣或許能將你說服。
          22.     如認為自己已進行了良好的分析、設計或者實施,那么請稍微更換一下思維角度。試試邀請一些外來人士——并不一定是專家,但可以是來自本公司其他部門的人。請他們用完全新鮮的眼光考察你的工作,看看是否能找出你一度熟視無睹的問題。采取這種方式,往往能在最適合修改的階段找出一些關鍵性的問題,避免產品發行后再解決問題而造成的金錢及精力方面的損失。
          23.     良好的設計能帶來最大的回報。簡言之,對于一個特定的問題,通常會花較長的時間才能找到一種最恰當的解決方案。但一旦找到了正確的方法,以后的工作就輕松多了,再也不用經歷數小時、數天或者數月的痛苦掙扎。我們的努力工作會帶來最大的回報(甚至無可估量)。而且由于自己傾注了大量心血,最終獲得一個出色的設計方案,成功的快感也是令人心動的。堅持抵制草草完工的誘惑——那樣做往往得不償失。

          posted on 2007-11-29 14:57 郭旺平 閱讀(718) 評論(2)  編輯  收藏

          評論

          # re: java編程規范(學java的第一步) 2007-12-07 02:31 cmpleo

          好詳細啊,謝一個  回復  更多評論   

          # re: java編程規范(學java的第一步)[未登錄] 2008-05-07 16:22 william

          很不錯,很詳細!  回復  更多評論   


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


          網站導航:
           

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆檔案(2)

          文章檔案(2)

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 子洲县| 盈江县| 金华市| 南通市| 高陵县| 丰镇市| 阿尔山市| 钟祥市| 苗栗县| 奉贤区| 庆元县| 萝北县| 赤峰市| 青铜峡市| 乌兰县| 南川市| 蕲春县| 凉山| 田阳县| 普兰店市| 彩票| 公安县| 双辽市| 卫辉市| 长武县| 新晃| 池州市| 汉川市| 古蔺县| 泸定县| 靖州| 平定县| 光泽县| 富源县| 开远市| 盐亭县| 彭泽县| 浦城县| 清原| 年辖:市辖区| 砀山县|