java編程規(guī)范(學java的第一步)
1 Java編程規(guī)范
1.1 命名約定
1.1.1 包的命名
JDK 的標準是——包名稱的所有字母均小寫,如:
package myownpackage;
1.1.2 類的命名
JDK 的標準是——大寫一個類名的首字母,若類名由幾個單詞構(gòu)成,那么把它們緊靠到一起(也就是說,不要用下劃線來分隔名字)。此外,每個嵌入單詞的首字母都要采用大寫形式。類名稱應該是一個名詞短語。如:
class ZipFileAccesser
1.1.3 變量的命名
1. ?變量命名一般原則(參照匈牙利命名法)(必須)
2. 能清楚表示變量的類型
3. 能簡明表達變量的涵義
4. ?常量的命名(必須)
5. 常量名稱全部大寫,如:
public final int PORT = 2000;
6. 主要基本類型變量的命名
主要類型名稱縮寫格式及規(guī)則:由類型全稱取一個字母組成 + 實際名稱,如:
String strTemp;
對幾種主要的基本類型變量命名前綴的規(guī)定(參見附錄A:基本命名參考)
7. 靜態(tài)變量的命名
靜態(tài)變量名稱以字符串“STATIC”開頭,如:
static int STATICintNumber;
8. 臨時變量的命名(推薦)
臨時性變量格式為(類型名稱縮寫 + Temp),如:
String strTemp=”asdf”;
9. 對象命名規(guī)則:
第一原則:當類名是由多單詞組成,取每個單詞的首字母,將其小寫形式組合而成變量名稱的前綴,當對象是由單個單詞組成時,取整個單詞的小寫形成作為變量名的前綴,如:
PrintWriter pwTemp;
Socket socketTemp;
第二原則:如果這樣命名時產(chǎn)生了重復現(xiàn)象,則和類型名稱縮寫提取原則類似,取三個小寫輔音字母或習慣性的用法,總之以能明顯區(qū)別類名稱為原則。如:ServletResponse 和ServletRequest 如果按照第一原則,兩個對象都可命名為srTemp,產(chǎn)生了重復,此時就應按照第二原則,命名為srpTemp 和srqTemp
10. 成員變量的命名
成員變量的命名原則與臨時變量相同,但在可能與臨時變量名稱重復的調(diào)用場合,應加上this.以示區(qū)別。推薦:對大多數(shù)成員變量調(diào)用的場合加上this.以利區(qū)別,如:
public String strUserName;
this.strUserName = strUserName;
1.1.4 方法的命名
方法名的第一個字母采用小寫,其他嵌入單詞首字母大寫。方法名應該是一個動賓結(jié)構(gòu)的短語,能夠簡明恰當?shù)谋磉_出方法完成的操作。如:
public String getStudentName(…);
1.1.5 其它說明:(推薦)
一般不允許使用數(shù)字和下劃線。如:
socket1,socket_num;
1.2 注釋
注釋采用javadoc的注釋方法,所有注釋放置于所注釋目標的上方。
1.2.1 類/接口的頭注釋
/**********************************************************
* 類描述信息
* @author 作者信息
* @version 版本信息,時間
* @since 創(chuàng)自信息
**********************************************************/
1.2.2 屬性的注釋
/**
* 注釋內(nèi)容
*/
1.2.3 方法的頭注釋
/**
* @param
* @return
* @throws
*/
注:每個參數(shù)名后必須有相應的說明,格式如下:
[參數(shù)名 參數(shù)說明]
如:
…
* @param intCounter 計數(shù)器
* @param strName 變量名稱
* @param blnFlag 標志位
…
返回值不必寫類型,如果沒有返回值或者返回值是void 就不寫@return,如:
* @return 當前的計數(shù)值
異常要逐個分行寫出,如:
* @throws IOException 如果發(fā)生I/O 錯誤
* @throws ZIPException 如果發(fā)生ZIP 文件錯誤
1.2.4 代碼內(nèi)的注釋
直接在代碼內(nèi)出現(xiàn)的注釋通常使得代碼易于理解。通過在前面加上一個空行和一個注釋行(或更多行)來概括大的操作。在需要時用每行后面的注釋或者更多的注釋來解釋較奇特的代碼。不止一行的注釋通常用/*…*/,而不是//,但//在行尾注釋中更好用。單行的注釋用兩種方法都可以,但推薦使用//。
1.2.5 未完成代碼的提醒注釋
/**
* @todo 注釋內(nèi)容
*/
1.3 代碼分隔
import …
空一行
package …
空一行
class …
1. 屬性與屬性間空一行,方法與方法之間空一行,類與類之間空一行。先寫公有屬性,后寫保護屬性,最后寫私有屬性。
2. 在方法內(nèi)部,幾行關(guān)系緊密的代碼之間應該不空行,但兩個相對獨立的代碼塊之間應空一行。一般,在方法內(nèi)部每隔3~5 行就應有一個空行。兩個相鄰空行之間的一段代碼為一個代碼塊,
3. 每隔代碼塊前面應有行注釋。
4. 構(gòu)造子必須放在其他所有方法前
5. 運算符兩邊要加一個空格,如:
intTotal = intAvg * intNum;
6. 括號兩邊內(nèi)側(cè)要各加一個空格,如:
void main ( String[ ] args );
7. 一行代碼只允許有一條語句,但這樣簡單的形式除外:
int ix, iy;
8. 減少public 域的定義,盡量通過方法而不是通過對象的實例直接訪問對象的域,并且所有的成員域必須加以說明。如:
String strUserName; //用戶名稱
1.4 代碼縮進原則
1. 類名、類體、方法體依次縮進一個單位長
2. 一個單位長是四個空格(可設(shè)為一個TAB 長)
1.5 雜項格式化約定
1. 在代碼塊之間使用空行,通過概括注釋來分隔。
2. 使行的長度限制在80個字符內(nèi)。
3. 用tab來縮進、每個tab長度為4個空格。
4. 左花括號與方法名處同一行,間隔一個空格。
5. 跳轉(zhuǎn)語句的標號與switch關(guān)鍵字對齊。
6. 像在英文中那樣使用空格(關(guān)鍵字和逗號后面加,括號后面不加,許多操作符之間加)。
2 附錄A:基本命名參考
2.1 構(gòu)造名稱
w 一般的匈牙利名稱是由三部分組成:一個或多個前綴,一個基本標簽和一個qualifier。
w 基本標簽表示了變量的類型(例如,“co”表示一種顏色)。
w 前綴修飾這個類型(例如,“rg”表示體格數(shù)組,所以“rgco”表示一個顏色數(shù)組)。
w qualifier描述了這種特定類型的具體用途(例如,“rgcoGray”表示一個作為灰色使用的顏色數(shù)組)。
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 |
數(shù)組(來自于“range”)。例如,“rgch”表示一個字符數(shù)組。 |
c |
某個基類條目的計數(shù)。例如,“cch”表示字符的計數(shù)。 |
d |
某種基類的值之間的差值或delta。例如,“dx”表示兩個x類型的值之間的差值。 |
此外,以下是我們在合適的時候可以在任何匈牙利前綴之前加入的特殊前綴:
m_ |
C++類的數(shù)據(jù)成員。 |
s_ |
C++類的靜態(tài)數(shù)據(jù)成員。 |
2.4 標準qualifier
First |
某集合中的第一個條目,或所關(guān)心的第一個條目(例如pchFirst)。 |
Last |
某集合的最后一個條目,或所關(guān)心的最后一個條目(例如,pchLast)。當作為下標使用時,Last表示最后一個有效的/希望的值,所以一個循環(huán)可能是: |
Lim |
某集合的元素個數(shù)上限。與Last不同,Lim不代表一個有效的值,Lim代表最后一個有效值后面的一個,所以一個循環(huán)可能是: for (ich = ichFirst; ich < ichLim; ich++) |
Min |
某集合的最小元素。與First相似,但通常表示第一個有效的值,而不是要處理的第一個值。 |
Max |
某集合的元素個數(shù)上限(與Lim相同)。不幸的是,標準的英文中的“Max”通常表示最后一個有效的值,但Max qualifier不是一個有效的值,它是最后一個有效值后面的一個。和Lim一樣,典型的用法應該是: for (ich = ichMin; ich < ichMax; ich++) |
Mac |
與Max相似,但有時可用在“當前”最大值可能隨時間變化的情況下。注意Mac也是代表“最后的”有效值之后的一個。 |
Mic |
與Min相似,但有時可用在“當前”最大值可能隨時間變化的情況下。 |
T |
臨時的值。這個qualifier可能會被過度使用,而不能為某些量起一個好名字,但有時少數(shù)的臨時值是可以的,比如在一個典型的交換操作中。 |
TT, T3, etc. |
這是在需要更確切的名字的時候?qū)?/span>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編程規(guī)則
選自《Think in java》,包含了大量有用的建議,幫助大家進行低級程序設(shè)計,并提供了代碼編寫的一般性指導:
1. 類名首字母應該大寫。字段、方法以及對象的首字母應小寫。對于所有標識符,其中包含的所有單詞都應緊靠在一起,而且大寫中間單詞的首字母。例如:
ThisIsAClassName
thisIsMethodOrFieldName
若在定義中出現(xiàn)了常數(shù)初始化字符,則大寫static final基本類型標識符中的所有字母。這樣便可標志出它們屬于編譯期的常數(shù)。
Java包(Package)屬于一種特殊情況:它們?nèi)际切懽帜?,即便中間的單詞亦是如此。對于域名擴展名稱,如com,org,net或者edu等,全部都應小寫(這也是Java 1.1和Java 1.2的區(qū)別之一)。
2. 為了常規(guī)用途而創(chuàng)建一個類時,請采取“經(jīng)典形式”,并包含對下述元素的定義:
equals()
hashCode()
toString()
clone()(implement Cloneable)
implement Serializable