Java基礎——java代碼規范詳細版


本Java代碼規范以SUN的標准Java代碼規范為基礎,為適應我們公司的實際需要,可能會做一些修改。本文檔中沒有說明的地方,請參看SUN Java標准代碼規范。如果兩邊有沖突,以SUN Java標准為准。

1. 標識符命名規范

1.1 概述

標識符的命名力求做到統一、達意和簡潔。

1.1.1 統一

統一是指,對於同一個概念,在程序中用同一種表示方法,比如對於供應商,既可以用supplier,也可以用provider,但是我們只能選定一個使用,至少在一個Java項目中保持統一。統一是作為重要的,如果對同一概念有不同的表示方法,會使代碼混亂難以理解。即使不能取得好的名稱,但是只要統一,閱讀起來也不會太困難,因為閱讀者只要理解一次。

1.1.2 達意

達意是指,標識符能准確的表達出它所代表的意義,比如: newSupplier, OrderPaymentGatewayService等;而 supplier1, service2,idtts等則不是好的命名方式。准確有兩成含義,一是正確,二是豐富。如果給一個代表供應商的變量起名是 order,顯然沒有正確表達。同樣的,supplier1, 遠沒有targetSupplier意義豐富。

1.1.3 簡潔

簡潔是指,在統一和達意的前提下,用盡量少的標識符。如果不能達意,寧願不要簡潔。比如:theOrderNameOfTheTargetSupplierWhichIsTransfered 太長, transferedTargetSupplierOrderName則較好,但是transTgtSplOrdNm就不好了。省略元音的縮寫方式不要使用,我們的英語往往還沒有好到看得懂奇怪的縮寫。

1.1.4 駱駝法則

Java中,除了包名,靜態常量等特殊情況,大部分情況下標識符使用駱駝法則,即單詞之間不使用特殊符號分割,而是通過首字母大寫來分割。比如: supplierName, addNewContract,而不是 supplier_name, add_new_contract。

1.1.5 英文 vs 拼音

盡量使用通俗易懂的英文單詞,如果不會可以向隊友求助,實在不行則使用漢語拼音,避免拼音與英文混用。比如表示歸檔,用archive比較好, 用pigeonhole則不好,用guiDang尚可接受。

1.2 包名

使用小寫字母如 com.xxx.settlment,不要 com.xxx.Settlement
單詞間不要用字符隔開,比如 com.xxx.settlment.jsfutil,而不要com.xxx.settlement.jsf_util

1.3 類名

1.3.1 首字母大寫

類名要首字母大寫,比如 SupplierService, PaymentOrderAction;不要 supplierService, paymentOrderAction.

1.3.2 后綴

類名往往用不同的后綴表達額外的意思,如下表:

1.4 方法名

首字母小寫,如 addOrder() 不要 AddOrder()
動詞在前,如 addOrder(),不要orderAdd()
動詞前綴往往表達特定的含義,如下表:

 

 

find方法在業務層盡量表達業務含義,比如 findUnsettledOrders(),查詢未結算訂單,而不要findOrdersByStatus()。 數據訪問層,find,update等方法可以表達要執行的sql,比如findByStatusAndSupplierIdOrderByName(Status.PAID, 345)

1.5 域(field)名

1.5.1 靜態常量

全大寫用下划線分割,如

public static find String ORDER_PAID_EVENT = “ORDER_PAID_EVENT”;

1.5.2 枚舉

全大寫,用下划線分割,如

public enum Events {
ORDER_PAID,
ORDER_CREATED

}

1.5.3 其他

首字母小寫,駱駝法則,如:

public String orderName;

1.6 局部變量名

參數和局部變量名首字母小寫,駱駝法則。盡量不要和域沖突,盡量表達這個變量在方法中的意義。

2. 代碼格式

用空格字符縮進源代碼,不要用tab,每個縮進4個空格。

2.1 源文件編碼

源文件使用utf-8編碼,結尾用unix n 分格。

2.2 行寬

行寬度不要超過80。Eclipse標准

2.3 包的導入

刪除不用的導入,盡量不要使用整個包的導入。在eclipse下經常使用快捷鍵 ctrl+shift+o 修正導入。

2.4 類格式

2.5 域格式

每行只能聲明一個域。
域的聲明用空行隔開。

2.5 方法格式

2.6 代碼塊格式

2.6.1 縮進風格

大括號的開始在代碼塊開始的行尾,閉合在和代碼塊同一縮進的行首,例如:

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;

}

}

}

2.6.2 空格的使用

2.6.2.1 表示分割時用一個空格

不能這樣:

if ( a > b ) {

//do something here

};

2.6.2.2 二元三元運算符兩邊用一個空格隔開

如下:

a + b = c;

b - d = e;

return a == b ? 1 : 0;

不能如下:

a+b=c;

b-d=e;

return a==b?1:0;

2.6.2.3 逗號語句后如不換行,緊跟一個空格

如下:

call(a, b, c);

不能如下:

call(a,b,c);

2.6.3 空行的使用

空行可以表達代碼在語義上的分割,注釋的作用范圍,等等。將類似操作,或一組操作放在一起不用空行隔開,而用空行隔開不同組的代碼, 如下:

order = orderDao.findOrderById(id);

 

//update properties

order.setUserName(userName);

order.setPrice(456);

order.setStatus(PAID);

orderService.updateTotalAmount(order);

session.saveOrUpdate(order);

上例中的空行,使注釋的作用域很明顯.

連續兩行的空行代表更大的語義分割。
方法之間用空行分割
域之間用空行分割
超過十行的代碼如果還不用空行分割,就會增加閱讀困難
3. 注釋規范

3.1 注釋 vs 代碼

注釋宜少而精,不宜多而濫,更不能誤導
命名達意,結構清晰, 類和方法等責任明確,往往不需要,或者只需要很少注釋,就可以讓人讀懂;相反,代碼混亂,再多的注釋都不能彌補。所以,應當先在代碼本身下功夫。
不能正確表達代碼意義的注釋,只會損害代碼的可讀性。
過於詳細的注釋,對顯而易見的代碼添加的注釋,羅嗦的注釋,還不如不寫。
注釋要和代碼同步,過多的注釋會成為開發的負擔
注釋不是用來管理代碼版本的,如果有代碼不要了,直接刪除,svn會有記錄的,不要注釋掉,否則以后沒人知道那段注釋掉的代碼該不該刪除。
3.2 Java Doc

表明類、域和方法等的意義和用法等的注釋,要以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() {

}

}

3.3 塊級別注釋

3.3.1 塊級別注釋,單行時用 //, 多行時用 /* .. */。

3.3.2 較短的代碼塊用空行表示注釋作用域

3.3.3 較長的代碼塊要用

/*------ 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: 訂單處理 ------- */

3.3.4 可以考慮使用大括號來表示注釋范圍

使用大括號表示注釋作用范圍的例子:

/*----------訂單處理 ------- */

{

//取得dao

OrderDao dao = Factory.getDao("OrderDao");

/* 查詢訂單 */

Order order = dao.findById(456);

 

//更新訂單

order.setUserName("uu");

order.setPassword("pass");

order.setPrice("ddd");

 

orderDao.save(order);

}

3.4 行內注釋

行內注釋用 // 寫在行尾

4 最佳實踐和禁忌

4.1 每次保存的時候,都讓你的代碼是最美的

程序員都是懶惰的,不要想着等我完成了功能,再來優化代碼的格式和結構,等真的把功能完成,很少有人會再願意回頭調整代碼。

4.2 使用log而不是System.out.println()

log可以設定級別,可以控制輸出到哪里,容易區分是在代碼的什么地方打印的,而System.out.print則不行。而且,System.out.print的速度很慢。所以,除非是有意的,否則,都要用log。至少在提交到svn之前把System.out.print換成log。

4.3 每個if while for等語句,都不要省略大括號{}

看下面的代碼:

if (a > b)

a++;

如果在以后維護的時候,需要在a > b 時,把b++,一步小心就會寫成:

if (a > b)

a++;

b++;

這樣就錯了,因為無論a和b是什么關系,b++都會執行。 如果一開始就這樣寫:

if (a > b) {

a++;

}

相信沒有哪個笨蛋會把b++添加錯的。而且,這個大括號使作用范圍更明顯,尤其是后面那行很長要折行時。

4.4 善用TODO:

在代碼中加入 //TODO: ,大部分的ide都會幫你提示,讓你知道你還有什么事沒有做。比如:

if (order.isPaid()) {

//TODO: 更新訂單

}

4.5 在需要留空的地方放一個空語句或注釋,告述讀者,你是故意的

比如:

if (!exists(order)) {

;

}

或:

if (!exists(order)) {

//nothing to do

}

4.6 不要再對boolean值做true false判斷

比如:

if (order.isPaid() == true) {

// Do something here

}

不如寫成:

if (order.isPaid()) {

//Do something here

}

后者讀起來就很是 if order is paid, …. 要比 if order’s isPaid method returns true, … 更容易理解

4.7 減少代碼嵌套層次

代碼嵌套層次達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();

}

}

}

}

減少嵌套的方法有很多:

合並條件
利用 return 以省略后面的else
利用子方法
比如上例,合並條件后成為:

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();

}

}

}

利用子方法,就是將嵌套的程序提取出來放到另外的方法里。

4.8 程序職責單一

關注點分離是軟件開發的真理。人類自所以能夠完成復雜的工作,就是因為人類能夠將工作分解到較小級別的任務上,在做每個任務時關注更少的東西。讓程序單元的職責單一,可以使你在編寫這段程序時關注更少的東西,從而降低難度,減少出錯。

4.9 變量的聲明,初始化和被使用盡量放到一起

比方說如下代碼:

int orderNum= getOrderNum();

//do something withou orderNum here

call(orderNum);

上例中的注釋處代表了一段和orderNum不相關的代碼。orderNum的聲明和初始化離被使用的地方相隔了很多行的代碼,這樣做不好,不如這樣:

//do something withou orderNum here

int orderNum= getOrderNum();

call(orderNum);

4.10 縮小變量的作用域

能用局部變量的,不要使用實例變量,能用實例變量的,不要使用類變量。變量的生存期越短,以為着它被誤用的機會越小,同一時刻程序員要關注的變量的狀態越少。實例變量和類變量默認都不是線程安全的,局部變量是線程安全的。比如如下代碼:

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);

}

}

4.11 盡量不要用參數來帶回方法運算結果

比如:

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

}

4.12 除非有相當充足的理由,否則不許使用省略泛型類的類型參數

養成良好的編碼規范,從我做起


參考原文:https://blog.csdn.net/qq_34869143/article/details/94554253


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM