1、儘可能使用接口,而後使用類實現接口,以提升程序的靈活性。 2、一行不要超過80個字符 3、儘可能不要手工更改計算機生成的代碼,若必須修改,必定要改爲和計算機生成的代碼風格同樣。 4、關鍵的語句(包括聲明關鍵的變量)必需要寫註釋。 5、建議局部變量在最接近使用它的地方聲明。 6、不要使用goto系列語句,除非是用在跳出深層循環時。 7、避免寫超過5個參數的方法。若是要傳遞多個參數,則使用結構。 8、避免書寫代碼量過大的try…catch模塊。 9、避免在同一個文件中放置多個類。 10、生成和構建一個長的字符串時,必定要使用StringBuilder類型,而不是string類型。 11、switch語句必定要有default語句來處理意外狀況。 12、對於if語句,應該使用一對「{}」把語句塊包含起來。 1三、儘可能不使用this關鍵字引用。
第一命名:java
類名的話,使用大駝峯,方法名和變量名採用小駝峯的樣式. 最好可以見名知意 例如程序員
public class Demo { public void demoBind() { } }
string strUserName;
本Java代碼規範以SUN的標準Java代碼規範爲基礎,爲適應咱們公司的實際須要,可能會作一些修改。本文檔中沒有說明的地方,請參看SUN Java標準代碼規範。若是兩邊有衝突,以本文檔爲準。sql
標識符的命名力求作到統1、達意和簡潔。安全
統一是指,對於同一個概念,在程序中用同一種表示方法,好比對於供應商,既能夠用supplier,也能夠用provider,可是咱們只能選定一個使用,至少在一個Java項目中保持統一。統一是做爲重要的,若是對同一律念有不一樣的表示方法,會使代碼混亂難以理解。即便不能取得好的名稱,可是隻要統一,閱讀起來也不會太困難,由於閱讀者只要理解一次。session
達意是指,標識符能準確的表達出它所表明的意義,好比: newSupplier, OrderPaymentGatewayService等;而 supplier1, service2,idtts等則不是好的命名方式。準確有兩成含義,一是正確,而是豐富。若是給一個表明供應商的變量起名是 order,顯然沒有正確表達。一樣的,supplier1, 遠沒有targetSupplier意義豐富。app
簡潔是指,在統一和達意的前提下,用盡可能少的標識符。若是不能達意,寧願不要簡潔。好比:theOrderNameOfTheTargetSupplierWhichIsTransfered 太長, transferedTargetSupplierOrderName則較好,可是transTgtSplOrdNm就很差了。省略元音的縮寫方式不要使用,咱們的英語每每尚未好到看得懂奇怪的縮寫。eclipse
Java中,除了包名,靜態常量等特殊狀況,大部分狀況下標識符使用駱駝法則,即單詞之間不使用特殊符號分割,而是經過首字母大寫來分割。好比: SupplierName, addNewContract,而不是 supplier_name, add_new_contract。ide
儘可能使用通俗易懂的英文單詞,若是不會能夠向隊友求助,實在不行則使用漢語拼音,避免拼音與英文混用。好比表示歸檔,用archive比較好, 用pigeonhole則很差,用guiDang尚可接受。svn
使用小寫字母如 com.xxx.settlment
,不要 com.xxx.Settlement
單詞間不要用字符隔開,好比 com.xxx.settlment.jsfutil
,而不要com.xxx.settlement.jsf_util
優化
類名要首字母大寫,好比 SupplierService, PaymentOrderAction;不要 supplierService, paymentOrderAction.
類名每每用不一樣的後綴表達額外的意思,以下表:
後綴名 | 意義 | 舉例 |
Service | 代表這個類是個服務類,裏面包含了給其餘類提同業務服務的方法 | PaymentOrderService |
Impl | 這個類是一個實現類,而不是接口 | PaymentOrderServiceImpl |
Inter | 這個類是一個接口 | LifeCycleInter |
Dao | 這個類封裝了數據訪問方法 | PaymentOrderDao |
Action | 直接處理頁面請求,管理頁面邏輯了類 | UpdateOrderListAction |
Listener | 響應某種事件的類 | PaymentSuccessListener |
Event | 這個類表明了某種事件 | PaymentSuccessEvent |
Servlet | 一個Servlet | PaymentCallbackServlet |
Factory | 生成某種對象工廠的類 | PaymentOrderFactory |
Adapter | 用來鏈接某種之前不被支持的對象的類 | DatabaseLogAdapter |
Job | 某種按時間運行的任務 | PaymentOrderCancelJob |
Wrapper | 這是一個包裝類,爲了給某個類提供沒有的能力 | SelectableOrderListWrapper |
Bean | 這是一個POJO | MenuStateBean |
首字母小寫,如 addOrder() 不要 AddOrder()
動詞在前,如 addOrder(),不要orderAdd()
動詞前綴每每表達特定的含義,以下表:
前綴名 | 意義 | 舉例 |
create | 建立 | createOrder() |
delete | 刪除 | deleteOrder() |
add | 建立,暗示新建立的對象屬於某個集合 | addPaidOrder() |
remove | 刪除 | removeOrder() |
init或則initialize | 初始化,暗示會作些諸如獲取資源等特殊動做 | initializeObjectPool |
destroy | 銷燬,暗示會作些諸如釋放資源的特殊動做 | destroyObjectPool |
open | 打開 | openConnection() |
close | 關閉 | closeConnection()< |
read | 讀取 | readUserName() |
write | 寫入 | writeUserName() |
get | 得到 | getName() |
set | 設置 | setName() |
prepare | 準備 | prepareOrderList() |
copy | 複製 | copyCustomerList() |
modity | 修改 | modifyActualTotalAmount() |
calculate | 數值計算 | calculateCommission() |
do | 執行某個過程或流程 | doOrderCancelJob() |
dispatch | 判斷程序流程轉向 | dispatchUserRequest() |
start | 開始 | startOrderProcessing() |
stop | 結束 | stopOrderProcessing() |
send | 發送某個消息或事件 | sendOrderPaidMessage() |
receive | 接受消息或時間 | receiveOrderPaidMessgae() |
respond | 響應用戶動做 | responseOrderListItemClicked() |
find | 查找對象 | findNewSupplier() |
update | 更新對象 | updateCommission() |
find方法在業務層儘可能表達業務含義,好比 findUnsettledOrders(),查詢未結算訂單,而不要findOrdersByStatus()。 數據訪問層,find,update等方法能夠表達要執行的sql,好比findByStatusAndSupplierIdOrderByName(Status.PAID, 345)
全大寫用下劃線分割,如
public static find String ORDER_PAID_EVENT = "ORDER_PAID_EVENT";
全大寫,用下劃線分割,如
public enum Events {
ORDER_PAID,
ORDER_CREATED
}
首字母小寫,駱駝法則,如:
public String orderName;
參數和局部變量名首字母小寫,駱駝法則。儘可能不要和域衝突,儘可能表達這個變量在方法中的意義。
用空格字符縮進源代碼,不要用tab,每一個縮進4個空格。
源文件使用utf-8編碼,結尾用unix n 分格。
行寬度不要超過130。
刪除不用的導入,儘可能不要使用整個包的導入。在eclipse下常用快捷鍵 ctrl+shift+o 修正導入。
每行只能聲明一個域。
域的聲明用空行隔開。
大括號的開始在代碼塊開始的行尾,閉合在和代碼塊同一縮進的行首,例如:
package com.test;
public class TestStyle extends SomeClass implements AppleInter, BananaInter {
public static final String THIS_IS_CONST = "CONST VALUE";
private static void main(String[] args) {
int localVariable = 0;
}
public void compute(String arg) {
if (arg.length() > 0) {
System.out.println(arg);
}
for (int i = 0; i < 10; i++) {
System.out.println(arg);
}
while (condition) {
}
do {
otherMethod();
} while (condition);
switch (i) {
case 0:
callFunction();
break;
case 1:
callFunctionb();
break;
default:
break;
}
}
}
不能這樣:
if ( a > b ) {
//do something here
};
以下:
a + b = c;
b - d = e;
return a == b ? 1 : 0;
不能以下:
a+b=c;
b-d=e;
return a==b?1:0;
以下:
call(a, b, c);
不能以下:
call(a,b,c);
空行能夠表達代碼在語義上的分割,註釋的做用範圍,等等。將相似操做,或一組操做放在一塊兒不用空行隔開,而用空行隔開不一樣組的代碼, 如圖:
order = orderDao.findOrderById(id);
//update properties
order.setUserName(userName);
order.setPrice(456);
order.setStatus(PAID);
orderService.updateTotalAmount(order);
session.saveOrUpdate(order);
上例中的空行,使註釋的做用域很明顯.
。
代表類、域和方法等的意義和用法等的註釋,要以javadoc的方式來寫。Java Doc是個類的使用者來看的,主要介紹 是什麼,怎麼用等信息。凡是類的使用者須要知道,都要用Java Doc 來寫。非Java Doc的註釋,每每是個代碼的維護者看的,着重告述讀者爲何這樣寫,如何修改,注意什麼問題等。 以下:
/**
* This is a class comment
*/
public class TestClass {
/**
* This is a field comment
*/
public String name;
/**
* This is a method comment
*/
public void call() {
}
}
/*------ start: ------*/
和
/*-------- end: -------*/
包圍
如:
/*----------start: 訂單處理 ------- */
//取得dao
OrderDao dao = Factory.getDao("OrderDao");
/* 查詢訂單 */
Order order = dao.findById(456);
//更新訂單
order.setUserName("uu");
order.setPassword("pass");
order.setPrice("ddd");
orderDao.save(order);
/*----------end: 訂單處理 ------- */
使用大括號表示註釋做用範圍的例子:
/*----------訂單處理 ------- */
{
//取得dao
OrderDao dao = Factory.getDao("OrderDao");
/* 查詢訂單 */
Order order = dao.findById(456);
//更新訂單
order.setUserName("uu");
order.setPassword("pass");
order.setPrice("ddd");
orderDao.save(order);
}
行內註釋用 // 寫在行尾
程序員都是懶惰的,不要想着等我完成了功能,再來優化代碼的格式和結構,等真的把功能完成,不多有人會再願意回頭調整代碼。
log能夠設定級別,能夠控制輸出到哪裏,容易區分是在代碼的什麼地方打印的,而System.out.print則不行。並且,System.out.print的速度很慢。因此,除非是有意的,不然,都要用log。至少在提交到svn以前把System.out.print換成log。
看下面的代碼:
if (a > b)
a++;
若是在之後維護的時候,須要在a > b 時,把b++,一步當心就會寫成:
if (a > b)
a++;
b++;
這樣就錯了,由於不管a和b是什麼關係,b++都會執行。 若是一開始就這樣寫:
if (a > b) {
a++;
}
相信沒有哪一個笨蛋會把b++添加錯的。並且,這個大括號使做用範圍更明顯,尤爲是後面那行很長要折行時。
在代碼中加入 //TODO: ,大部分的ide都會幫你提示,讓你知道你還有什麼事沒有作。好比:
if (order.isPaid()) {
//TODO: 更新訂單
}
好比:
if (!exists(order)) {
;
}
或:
if (!exists(order)) {
//nothing to do
}
好比:
if (order.isPaid() == true) {
// Do something here
}
不如寫成:
if (order.isPaid()) {
//Do something here
}
後者讀起來就非常 if order is paid, .... 要比 if order's isPaid method returns true, … 更容易理解
代碼嵌套層次達3層以上時,通常人理解起來都會困難。下面的代碼是一個簡單的例子:
public void demo(int a, int b, int c) {
if (a > b) {
if (b > c) {
doJobA();
} else if (b < c) {
doJobB()
}
} else {
if (b > c) {
if (a < c) {
doJobC();
}
}
}
}
減小嵌套的方法有不少:
好比上例,合併條件後成爲:
public void demo(int a, int b, int c) {
if (a > b && b > c) {
doJobA();
}
if (a > b && c > b) {
doJobB();
}
if (a <= b && c < b && a < c) {
doJobC();
}
}
若是利用return 則成爲:
public void demo(int a, int b, int c) {
if (a > b) {
if (b > c) {
doJobA();
return;
}
doJobB()
return;
}
if (b > c) {
if (a < c) {
doJobC();
}
}
}
利用子方法,就是將嵌套的程序提取出來放到另外的方法裏。
關注點分離是軟件開發的真理。人類自因此可以完成複雜的工做,就是由於人類可以將工做分解到較小級別的任務上,在作每一個任務時關注更少的東西。讓程序單元的職責單一,可使你在編寫這段程序時關注更少的東西,從而下降難度,減小出錯。
比方說以下代碼:
int orderNum= getOrderNum();
//do something withou orderNum here
call(orderNum);
上例中的註釋處表明了一段和orderNum不相關的代碼。orderNum的聲明和初始化離被使用的地方相隔了不少行的代碼,這樣作很差,不如這樣:
//do something withou orderNum here
int orderNum= getOrderNum();
call(orderNum);
能用局部變量的,不要使用實例變量,能用實例變量的,不要使用類變量。變量的生存期越短,覺得着它被誤用的機會越小,同一時刻程序員要關注的變量的狀態越少。實例變量和類變量默認都不是線程安全的,局部變量是線程安全的。好比以下代碼:
public class OrderPayAction{
private Order order;
public void doAction() {
order = orderDao.findOrder();
doJob1();
doJob2();
}
private void doJob1() {
doSomething(order);
}
private void doJob2() {
doOtherThing(order);
}
}
上例中order只不過擔當了在方法間傳遞參數之用,用下面的方法更好:
public class OrderPayAction{
public void doAction() {
order = orderDao.findOrder();
doJob1(order);
doJob2(order);
}
private void doJob1(Order order) {
doSomething(order);
}
private void doJob2(Order order) {
doOtherThing(order);
}
}
好比:
public void calculate(Order order) {
int result = 0;
//do lots of computing and store it in the result
order.setResult(result);
}
public void action() {
order = orderDao.findOrder();
calculate(order);
// do lots of things about order
}
例子中calculate方法經過傳入的order對象來存儲結果, 不如以下寫:
public int calculate(Order order) {
int result = 0;
//do lots of computing and store it in the result
return result;
}
public void action() {
order = orderDao.findOrder();
order.setResult(calculate(order));
// do lots of things about order}