項(xiàng)目開發(fā)規(guī)范
一、目的
對(duì)于代碼,首要要求是它必須正確,能夠按照程序員的真實(shí)思想去運(yùn)行;第二個(gè)的要求是代碼必須清晰易懂,使別的程序員能夠容易理解代碼所進(jìn)行的實(shí)際工作。在軟件工程領(lǐng)域,源程序的風(fēng)格統(tǒng)一標(biāo)志著可維護(hù)性、可讀性,是軟件項(xiàng)目的一個(gè)重要組成部分。而目前還沒有成文的編碼風(fēng)格文檔,以致于很多時(shí)候,程序員沒有一個(gè)共同的標(biāo)準(zhǔn)可以遵守,編碼風(fēng)格各異,程序可維護(hù)性差、可讀性也很差。通過建立代碼編寫規(guī)范,形成開發(fā)小組編碼約定,提高程序的可靠性、可讀性、可修改性、可維護(hù)性、可繼承性和一致性,可以保證程序代碼的質(zhì)量,繼承軟件開發(fā)成果,充分利用資源,使開發(fā)人員之間的工作成果可以共享。
本文在參考業(yè)界已有的編碼風(fēng)格的基礎(chǔ)上,描述了一個(gè)基于 JBuilder 的項(xiàng)目風(fēng)格,力求一種統(tǒng)一的編程風(fēng)格,并從整體編碼風(fēng)格、代碼文件風(fēng)格、函數(shù)編寫風(fēng)格、變量風(fēng)格、注釋風(fēng)格等幾個(gè)方面進(jìn)行闡述。(這些規(guī)范并不是一定要絕對(duì)遵守,但是一定要讓程序有良好的可讀性)
二、整體編碼風(fēng)格
1、縮進(jìn)
縮進(jìn)建議以4個(gè)空格為單位。建議在 Tools/Editor Options 中設(shè)置 Editor 頁面的Block ident為4,Tab Size 為8。預(yù)處理語句、全局?jǐn)?shù)據(jù)、標(biāo)題、附加說明、函數(shù)說明、標(biāo)號(hào)等均頂格書寫。語句塊的"{"、"}"配對(duì)對(duì)齊,并與其前一行對(duì)齊,語句塊類的語句縮進(jìn)建議每個(gè)"{"、"}"單獨(dú)占一行,便于匹對(duì)。JBuilder 中的默認(rèn)方式是開始的"{"不是單獨(dú)一行,建議更改成上述格式(在 Project/Default Project Properties 中設(shè)置 Code Style 中選擇 Braces 為 Next line)。
2、空格
原則上變量、類、常量數(shù)據(jù)和函數(shù)在其類型,修飾名稱之間適當(dāng)空格并據(jù)情況對(duì)齊。關(guān)鍵字原則上空一格,如:if ( ... 等。運(yùn)算符的空格規(guī)定如下:"::"、"->"、"["、"]"、"++"、"--"、"~"、"!"、"+"、"-"(指正負(fù)號(hào))、"&"(引用)等幾個(gè)運(yùn)算符兩邊不加空格(其中單目運(yùn)算符系指與操作數(shù)相連的一邊),其它運(yùn)算符(包括大多數(shù)二目運(yùn)算符和三目運(yùn)算符"?:"兩邊均加一空格,在作函數(shù)定義時(shí)還可據(jù)情況多空或不空格來對(duì)齊,但在函數(shù)實(shí)現(xiàn)時(shí)可以不用。","運(yùn)算符只在其后空一格,需對(duì)齊時(shí)也可不空或多空格。不論是否有括號(hào),對(duì)語句行后加的注釋應(yīng)用適當(dāng)空格與語句隔開并盡可能對(duì)齊。個(gè)人認(rèn)為此項(xiàng)可以依照個(gè)人習(xí)慣決定遵循與否。
3、對(duì)齊
原則上關(guān)系密切的行應(yīng)對(duì)齊,對(duì)齊包括類型、修飾、名稱、參數(shù)等各部分對(duì)齊。另每一行的長度不應(yīng)超過屏幕太多,必要時(shí)適當(dāng)換行,換行時(shí)盡可能在","處或運(yùn)算符處,換行后最好以運(yùn)算符打頭,并且以下各行均以該語句首行縮進(jìn),但該語句仍以首行的縮進(jìn)為準(zhǔn),即如其下一行為“{”應(yīng)與首行對(duì)齊。
變量定義最好通過添加空格形成對(duì)齊,同一類型的變量最好放在一起。如下例所示:
int Value;
int Result;
int Length;
DWORD Size;
DWORD BufSize;
個(gè)人認(rèn)為此項(xiàng)可以依照個(gè)人習(xí)慣決定遵循與否。
4、空行
不得存在無規(guī)則的空行,比如說連續(xù)十個(gè)空行。程序文件結(jié)構(gòu)各部分之間空兩行,若不必要也可只空一行,各函數(shù)實(shí)現(xiàn)之間一般空兩行,由于每個(gè)函數(shù)還要有函數(shù)說明注釋,故通常只需空一行或不空,但對(duì)于沒有函數(shù)說明的情況至少應(yīng)再空一行。對(duì)自己寫的函數(shù),建議也加上“//------”做分隔。函數(shù)內(nèi)部數(shù)據(jù)與代碼之間應(yīng)空至少一行,代碼中適當(dāng)處應(yīng)以空行空開,建議在代碼中出現(xiàn)變量聲明時(shí),在其前空一行。類中四個(gè)“p”之間至少空一行,在其中的數(shù)據(jù)與函數(shù)之間也應(yīng)空行。
5、注釋
注釋是軟件可讀性的具體體現(xiàn)。程序注釋量一般占程序編碼量的20%,軟件工程要求不少于20%。程序注釋不能用抽象的語言,類似于"處理"、"循環(huán)"這樣的計(jì)算機(jī)抽象語言,要精確表達(dá)出程序的處理說明。例如:"計(jì)算凈需求"、"計(jì)算第一道工序的加工工時(shí)"等。避免每行程序都使用注釋,可以在一段程序的前面加一段注釋,具有明確的處理邏輯。
注釋必不可少,但也不應(yīng)過多,不要被動(dòng)的為寫注釋而寫注釋。以下是四種必要的注釋:
A. 標(biāo)題、附加說明。
B. 函數(shù)、類等的說明。對(duì)幾乎每個(gè)函數(shù)都應(yīng)有適當(dāng)?shù)恼f明,通常加在函數(shù)實(shí)現(xiàn)之前,在沒有函數(shù)實(shí)現(xiàn)部分的情況下則加在函數(shù)原型前,其內(nèi)容主要是函數(shù)的功能、目的、算法等說明,參數(shù)說明、返回值說明等,必要時(shí)還要有一些如特別的軟硬件要求等說明。公用函數(shù)、公用類的聲明必須由注解說明其使用方法和設(shè)計(jì)思路,當(dāng)然選擇恰當(dāng)?shù)拿袷侥軌驇椭惆咽虑榻忉尩酶宄?/FONT>
C. 在代碼不明晰或不可移植處必須有一定的說明。
D. 及少量的其它注釋,如自定義變量的注釋、代碼書寫時(shí)間等。
注釋有塊注釋和行注釋兩種,分別是指:"/**/"和"http://"建議對(duì)A用塊注釋,D用行注釋,B、C則視情況而定,但應(yīng)統(tǒng)一,至少在一個(gè)單元中B類注釋形式應(yīng)統(tǒng)一。具體對(duì)不同文件、結(jié)構(gòu)的注釋會(huì)在后面詳細(xì)說明。
6、代碼長度
對(duì)于每一個(gè)函數(shù)建議盡可能控制其代碼長度為53行左右,超過53行的代碼要重新考慮將其拆分為兩個(gè)或兩個(gè)以上的函數(shù)。函數(shù)拆分規(guī)則應(yīng)該一不破壞原有算法為基礎(chǔ),同時(shí)拆分出來的部分應(yīng)該是可以重復(fù)利用的。對(duì)于在多個(gè)模塊或者窗體中都要用到的重復(fù)性代碼,完全可以將起獨(dú)立成為一個(gè)具備公用性質(zhì)的函數(shù),放置于一個(gè)公用模塊中。
7、頁寬
頁寬應(yīng)該設(shè)置為80字符。源代碼一般不會(huì)超過這個(gè)寬度, 并導(dǎo)致無法完整顯示, 但這一設(shè)置也可以靈活調(diào)整. 在任何情況下, 超長的語句應(yīng)該在一個(gè)逗號(hào)或者一個(gè)操作符后折行. 一條語句折行后, 應(yīng)該比原來的語句再縮進(jìn)2個(gè)字符.
8、行數(shù)
一般的集成編程環(huán)境下,每屏大概只能顯示不超過50行的程序,所以這個(gè)函數(shù)大概要5-6屏顯示,在某些環(huán)境下要8屏左右才能顯示完。這樣一來,無論是讀程序還是修改程序,都會(huì)有困難。因此建議把完成比較獨(dú)立功能的程序塊抽出,單獨(dú)成為一個(gè)函數(shù)。把完成相同或相近功能的程序塊抽出,獨(dú)立為一個(gè)子函數(shù)。可以發(fā)現(xiàn),越是上層的函數(shù)越簡單,就是調(diào)用幾個(gè)子函數(shù),越是底層的函數(shù)完成的越是具體的工作。這是好程序的一個(gè)標(biāo)志。這樣,我們就可以在較上層函數(shù)里容易控制整個(gè)程序的邏輯,而在底層的函數(shù)里專注于某方面的功能的實(shí)現(xiàn)了。
三、代碼文件風(fēng)格
所有的 Java(*.java) 文件都必須遵守如下的樣式規(guī)則:
. 文件生成
對(duì)于規(guī)范的 JAVA 派生類,盡量用 JBuilder 的 Object Gallery 工具來生成文件格式,避免用手工制作的頭文件/實(shí)現(xiàn)文件。
. package/import
package 行要在 import 行之前,import 中標(biāo)準(zhǔn)的包名要在本地的包名之前,而且按照字母順序排列。如果 import 行中包含了同一個(gè)包中的不同子目錄,則應(yīng)該用 * 來處理。
package hotlava.net.stats;
import java.io.*;
import java.util.Observable;
import hotlava.util.Application;
這里 java.io.* 使用來代替InputStream and OutputStream 的。
. 文件頭部注釋
文件頭部注釋主要是表明該文件的一些信息,是程序的總體說明,可以增強(qiáng)程序的可讀性和可維護(hù)性。文件頭部注釋一般位于 package/imports 語句之后,Class 描述之前。要求至少寫出文件名、創(chuàng)建者、創(chuàng)建時(shí)間和內(nèi)容描述。JBuilder 的 Object Gallery 工具生成的代碼中會(huì)在類、工程文件中等自動(dòng)添加注釋,我們也要添加一些注釋,其格式應(yīng)該盡量約束如下:
/**
* Title: 確定鼠標(biāo)位置類
* Description: 確定鼠標(biāo)當(dāng)前在哪個(gè)作業(yè)欄位中并返回作業(yè)號(hào)
* @Copyright: Copyright (c) 2002
* @Company: HIT
* @author: rivershan
* @version: 1.0
* @time: 2002.10.30
*/
. Class
接下來的是類的注釋,一般是用來解釋類的。
/**
* 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
*/
接下來是類定義,包含了在不同的行的 extends 和 implements
public class CounterSet
extends Observable
implements Cloneable
.Class Fields
接下來是類的成員變量:
/**
* Packet counters
*/
protected int[] packets;
public 的成員變量必須生成文檔(JavaDoc)。proceted、private和 package 定義的成員變量如果名字含義明確的話,可以沒有注釋。
. 存取方法
接下來是類變量的存取的方法。它只是簡單的用來將類的變量賦值獲取值的話,可以簡單的寫在一行上。(個(gè)人認(rèn)為盡量分行寫)
/**
* Get the counters
* @return an array containing the statistical data. This array has been
* freshly allocated and can be modified by the caller.
*/
public int[] getPackets()
{
return copyArray(packets, offset);
}
public int[] getBytes()
{
return copyArray(bytes, offset);
}
public int[] getPackets()
{
return packets;
}
public void setPackets(int[] packets)
{
this.packets = packets;
}
其它的方法不要寫在一行上
. 構(gòu)造函數(shù)
接下來是構(gòu)造函數(shù),它應(yīng)該用遞增的方式寫(比如:參數(shù)多的寫在后面)。
訪問類型("public","private" 等.)和任何"static","final"或"synchronized"應(yīng)該在一行中,并且方法和參數(shù)另寫一行,這樣可以使方法和參數(shù)更易讀。
public
CounterSet(int size)
{
this.size = size;
}
. 克隆方法
如果這個(gè)類是可以被克隆的,那么下一步就是 clone 方法:
public
Object clone()
{
try
{
CounterSet obj = (CounterSet)super.clone();
obj.packets = (int[])packets.clone();
obj.size = size;
return obj;
}
catch(CloneNotSupportedException e)
{
throw new InternalError("Unexpected CloneNotSUpportedException: "
+ e.getMessage());
}
}
. 類方法
下面開始寫類的方法:
/**
* 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);
}
. toString 方法
無論如何,每一個(gè)類都應(yīng)該定義 toString 方法:
public
String toString()
{
String retval = "CounterSet: ";
for (int i = 0; i < data.length(); i++)
{
retval += data.bytes.toString();
retval += data.packets.toString();
}
return retval;
}
. main 方法
如果main(String[]) 方法已經(jīng)定義了, 那么它應(yīng)該寫在類的底部.
四、函數(shù)編寫風(fēng)格
. 函數(shù)的命名
通常,函數(shù)的命名也是以能表達(dá)函數(shù)的動(dòng)作意義為原則的,一般是由動(dòng)詞打頭,然后跟上表示動(dòng)作對(duì)象的名詞,各單詞的首字母應(yīng)該大寫。另外,還有一些函數(shù)命名的通用規(guī)則。如取數(shù),則用Get打頭,然后跟上要取的對(duì)象的名字;設(shè)置數(shù),則用Set打頭,然后跟上要設(shè)的對(duì)象的名字;而對(duì)象中為了響應(yīng)消息進(jìn)行動(dòng)作的函數(shù),可以命名為On打頭,然后是相應(yīng)的消息的名稱;進(jìn)行主動(dòng)動(dòng)作的函數(shù),可以命名為Do打頭,然后是相應(yīng)的動(dòng)作名稱。類似的規(guī)則還有很多,需要程序員多讀優(yōu)秀的程序,逐漸積累經(jīng)驗(yàn),才能作出好的函數(shù)命名。
. 函數(shù)注釋
系統(tǒng)自動(dòng)生成的函數(shù),如鼠標(biāo)動(dòng)作響應(yīng)函數(shù)等,不必太多的注釋和解釋;
對(duì)于自行編寫的函數(shù),若是系統(tǒng)關(guān)鍵函數(shù),則必須在函數(shù)實(shí)現(xiàn)部分的上方標(biāo)明該函數(shù)的信息,格式如下:
/**
* 函數(shù)名:
* 編寫者:
* 參考資料:
* 功 能:
* 輸入?yún)?shù):
* 輸出參數(shù):
* 備 注:
*/
希望盡量遵循以上格式。
五、符號(hào)風(fēng)格
. 總體要求
對(duì)于各種符號(hào)的定義,都有一個(gè)共通點(diǎn),就是應(yīng)該使用有實(shí)際意義的英文單詞或英文單詞的縮寫,不要使用簡單但沒有意義的字串,盡可能不使用阿拉伯?dāng)?shù)字,更切忌使用中文拼音的首字母。如這樣的名稱是不提倡的:Value1,Value2,Value3,Value4 …。
例如:
file(文件),code(編號(hào)),data(數(shù)據(jù)),pagepoint(頁面指針), faxcode(傳真號(hào)) ,address(地址),bank(開戶銀行),……
. 變量名稱
變量命名由(前綴+修飾語)構(gòu)成。現(xiàn)在比較流行的是一套由微軟的一個(gè)匈牙利軟件工程師首先使用,并且在微軟推廣開來,現(xiàn)在被稱之為匈牙利命名法的命名規(guī)則。匈牙利命名法規(guī)定,使用表示標(biāo)識(shí)符所對(duì)應(yīng)的變量類型的英文小寫縮寫作為標(biāo)識(shí)符的前綴,后面在使用表示變量意義的英文單詞或縮寫進(jìn)行命名。下面是匈牙利命名法中的一些命名方式:
(1)生存期修飾:用l(local)表示局域變量,p(public)表示全局變量,s(send)表示參數(shù)變量
(2)類型修飾:用s(AnsiString)表示字符串,c(char)表示字符,n(number)數(shù)值,i(intger)表示整數(shù),d(double)表示雙精度,f(float)浮點(diǎn)型,b(bool)布爾型,d(date)表示日期型.
例如:
li_length表示整形的局域變量,是用來標(biāo)識(shí)長度的.ls_code表示字符型的局域變量,用來標(biāo)識(shí)代碼.
. 控件名稱
控件命名由(前綴+修飾語)構(gòu)成。前綴即為控件的名稱。
按鈕變量 Button+Xxxxxxx 例如:ButtonSave,ButtonExit,ButtonPrint等
題標(biāo)變量 Label+Xxxxxxxx 例如:LabelName,LabelSex等
數(shù)據(jù)表變量 Table+Xxxxxx 例如:TableFile,TableCount等
查詢變量 Query+Xxxxxx 例如:QueryFile,QueryCeneter等
數(shù)據(jù)源變量 DataSource+Xxx 例如:DataSourceFile,DataSourceCenter等
。。。。。。。。。。。。。。。。
(注:對(duì)于與表有關(guān)的控件“修飾語”部分最好直接用表名。)
. Package 的命名
Package 的名字應(yīng)該都是由一個(gè)小寫單詞組成。
. Class 的命名
Class 的名字必須由一個(gè)或數(shù)個(gè)能表達(dá)該類的意思的大寫字母開頭而其它字母都小寫的單詞或縮寫組成,這樣能使這個(gè) Class 的名稱能更容易被理解。
. Class 變量的命名
變量的名字必須用一個(gè)小寫字母開頭。后面的單詞用大寫字母開頭。對(duì)于類的成員變量,在對(duì)其標(biāo)識(shí)符命名時(shí),要加上代表member(成員)的前綴m_。例如一個(gè)標(biāo)識(shí)符為m_dwFlag,則它表示的變量是一個(gè)類型為雙字的成員變量,它是代表一個(gè)標(biāo)志。
. Static Final 變量的命名
Static Final 變量的名字應(yīng)該都大寫,并且指出完整含義。
. 參數(shù)的命名
參數(shù)的名字必須和變量的命名規(guī)范一致。
. 數(shù)組的命名
數(shù)組應(yīng)該總是用下面的方式來命名:
byte[] buffer;
而不是:
byte buffer[];
. 方法的參數(shù)
使用有意義的參數(shù)命名,如果可能的話,使用和要賦值的字段一樣的名字:
SetCounter(int size)
{
this.size = size;
}
. 神秘的數(shù)
首先要說什么是神秘的數(shù)。我們?cè)诔绦蚶锝?jīng)常會(huì)用到一些量,它是有特定的含義的。例如,現(xiàn)在我們寫一個(gè)薪金統(tǒng)計(jì)程序,公司員工有50人,我們?cè)诔绦蚶锞蜁?huì)用50這個(gè)數(shù)去進(jìn)行各種各樣的運(yùn)算。在這里,50就是"神秘的數(shù)"。為什么稱它為神秘呢?因?yàn)閯e的程序員在程序里看到50這個(gè)數(shù),不知道它的含義,只能靠猜了。
在程序里出現(xiàn)"神秘的數(shù)"會(huì)降低程序的可讀性,應(yīng)該盡量避免。避免的方法是把神秘的數(shù)定義為一個(gè)常量。注意這個(gè)常量的命名應(yīng)該能表達(dá)該數(shù)的意義,并且應(yīng)該全部大寫,以與對(duì)應(yīng)于變量的標(biāo)識(shí)符區(qū)別開來。例如上面50這個(gè)數(shù),我們可以定義為一個(gè)名為NUMOFEMPLOYEES的常量來代替。這樣,別的程序員在讀程序的時(shí)候就可以容易理解了。
六、程序編寫風(fēng)格
. exit()
exit 除了在 main 中可以被調(diào)用外,其他的地方不應(yīng)該調(diào)用。因?yàn)檫@樣做不給任何代碼代碼機(jī)會(huì)來截獲退出。一個(gè)類似后臺(tái)服務(wù)地程序不應(yīng)該因?yàn)槟骋粋€(gè)庫模塊決定了要退出就退出。
. 異常
申明的錯(cuò)誤應(yīng)該拋出一個(gè)RuntimeException或者派生的異常。
頂層的main()函數(shù)應(yīng)該截獲所有的異常,并且打印(或者記錄在日志中)在屏幕上。
. 垃圾收集
JAVA使用成熟的后臺(tái)垃圾收集技術(shù)來代替引用計(jì)數(shù)。但是這樣會(huì)導(dǎo)致一個(gè)問題:你必須在使用完對(duì)象的實(shí)例以后進(jìn)行清場工作。比如一個(gè)prel的程序員可能這么寫:
...
{
FileOutputStream fos = new FileOutputStream(projectFile);
project.save(fos, "IDE Project File";
}
...
除非輸出流一出作用域就關(guān)閉,非引用計(jì)數(shù)的程序語言,比如JAVA,是不能自動(dòng)完成變量的清場工作的。必須象下面一樣寫:
FileOutputStream fos = new FileOutputStream(projectFile);
project.save(fos, "IDE Project File";
fos.close();
. Clone
下面是一種有用的方法:
implements Cloneable
public
Object clone()
{
try
{
ThisClass obj = (ThisClass)super.clone();
obj.field1 = (int[])field1.clone();
obj.field2 = field2;
return obj;
}
catch(CloneNotSupportedException e)
{
throw new InternalError("Unexpected CloneNotSUpportedException: " + e.getMessage());
}
}
. final 類
絕對(duì)不要因?yàn)樾阅艿脑驅(qū)㈩惗x為 final 的(除非程序的框架要求)
如果一個(gè)類還沒有準(zhǔn)備好被繼承,最好在類文檔中注明,而不要將她定義為 final 的。這是因?yàn)闆]有人可以保證會(huì)不會(huì)由于什么原因需要繼承她。
. 訪問類的成員變量
大部分的類成員變量應(yīng)該定義為 protected 的來防止繼承類使用他們。
注意,要用"int[] packets",而不是"int packets[]",后一種永遠(yuǎn)也不要用。
public void setPackets(int[] packets)
{
this.packets = packets;
}
CounterSet(int size)
{
this.size = size;
}
. byte 數(shù)組轉(zhuǎn)換到 characters
為了將 byte 數(shù)組轉(zhuǎn)換到 characters,你可以這么做:
"Hello world!".getBytes();
. Utility 類
Utility 類(僅僅提供方法的類)應(yīng)該被申明為抽象的來防止被繼承或被初始化。
. 初始化
下面的代碼是一種很好的初始化數(shù)組的方法:
objectArguments = new Object[]
{
arguments
};
. 枚舉類型
JAVA 對(duì)枚舉的支持不好,但是下面的代碼是一種很有用的模板:
class Colour
{
public static final Colour BLACK = new Colour(0, 0, 0);
public static final Colour RED = new Colour(0xFF, 0, 0);
public static final Colour GREEN = new Colour(0, 0xFF, 0);
public static final Colour BLUE = new Colour(0, 0, 0xFF);
public static final Colour WHITE = new Colour(0xFF, 0xFF, 0xFF);
}
這種技術(shù)實(shí)現(xiàn)了RED, GREEN, BLUE 等可以象其他語言的枚舉類型一樣使用的常量。 他們可以用 '==' 操作符來比較。
但是這樣使用有一個(gè)缺陷:如果一個(gè)用戶用這樣的方法來創(chuàng)建顏色 BLACK
new Colour(0,0,0)
那么這就是另外一個(gè)對(duì)象,'=='操作符就會(huì)產(chǎn)生錯(cuò)誤。她的 equal() 方法仍然有效。由于這個(gè)原因,這個(gè)技術(shù)的缺陷最好注明在文檔中,或者只在自己的包中使用。
. 混合使用 AWT 和 Swing 組件
如果要將 AWT 組件和 Swing 組件混合起來使用的話,請(qǐng)小心使用。實(shí)際上,盡量不要將他們混合起來使用。
. 滾動(dòng)的 AWT 組件
AWT 組件絕對(duì)不要用 JscrollPane 類來實(shí)現(xiàn)滾動(dòng)。滾動(dòng) AWT 組件的時(shí)候一定要用 AWT ScrollPane 組件來實(shí)現(xiàn)。
. 避免在 InternalFrame 組件中使用 AWT 組件
盡量不要這么做,要不然會(huì)出現(xiàn)不可預(yù)料的后果。
. Z-Order 問題
AWT 組件總是顯示在 Swing 組件之上。當(dāng)使用包含 AWT 組件的 POP-UP 菜單的時(shí)候要小心,盡量不要這樣使用。
八、性能
在寫代碼的時(shí)候,從頭至尾都應(yīng)該考慮性能問題。這不是說時(shí)間都應(yīng)該浪費(fèi)在優(yōu)化代碼上,而是我們時(shí)刻應(yīng)該提醒自己要注意代碼的效率。比如:如果沒有時(shí)間來實(shí)現(xiàn)一個(gè)高效的算法,那么我們應(yīng)該在文檔中記錄下來,以便在以后有空的時(shí)候再來實(shí)現(xiàn)她。
不是所有的人都同意在寫代碼的時(shí)候應(yīng)該優(yōu)化性能這個(gè)觀點(diǎn)的,他們認(rèn)為性能優(yōu)化的問題應(yīng)該在項(xiàng)目的后期再去考慮,也就是在程序的輪廓已經(jīng)實(shí)現(xiàn)了以后。
. 不必要的對(duì)象構(gòu)造
不要在循環(huán)中構(gòu)造和釋放對(duì)象
. 使用 StringBuffer 對(duì)象
在處理 String 的時(shí)候要盡量使用 StringBuffer 類,StringBuffer 類是構(gòu)成 String 類的基礎(chǔ)。String 類將 StringBuffer 類封裝了起來,(以花費(fèi)更多時(shí)間為代價(jià))為開發(fā)人員提供了一個(gè)安全的接口。當(dāng)我們?cè)跇?gòu)造字符串的時(shí)候,我們應(yīng)該用 StringBuffer 來實(shí)現(xiàn)大部分的工作,當(dāng)工作完成后將 StringBuffer 對(duì)象再轉(zhuǎn)換為需要的 String 對(duì)象。比如:如果有一個(gè)字符串必須不斷地在其后添加許多字符來完成構(gòu)造,那么我們應(yīng)該使用 StringBuffer 對(duì)象和她的 append() 方法。如果我們用 String 對(duì)象代替 StringBuffer 對(duì)象的話,會(huì)花費(fèi)許多不必要的創(chuàng)建和釋放對(duì)象的 CPU 時(shí)間。
. 避免太多的使用 synchronized 關(guān)鍵字
避免不必要的使用關(guān)鍵字 synchronized,應(yīng)該在必要的時(shí)候再使用她,這是一個(gè)避免死鎖的好方法。
rivershan 原創(chuàng)于2002.11.5