在程序員的世界裏有兩件最討厭的事情,第一件事情是討厭寫代碼註釋,第二件事情是討厭看別人的代碼不寫註釋。雖然這只是個段子,但也反映了當下很多程序員的心聲。下面簡單介紹下代碼規範的重要性,第一,規範的代碼可以促進團隊合作,第二,規範的代碼可以減少bug處理,第三,規範的代碼可以降低維護成本,第四,規範的代碼有助於代碼審查,第五,養成代碼規範的習慣,有助於程序員自身的成長。
本系列文章將整合 阿里巴巴《Java開發手冊》 和 谷歌《Java編程規範》 ,總結Java開發過程的編碼規範,並通過具體編碼案例給出編碼規範的原因,如果總結內容存在問題還望指出。
目錄
本篇將繼續介紹Java開發規範過程的代碼格式問題,代碼格式一般是指代碼的表現形式,如空格,對齊樣式,長度控制等,由於篇幅內容較多將分爲上下兩篇,下篇文章鏈接 Java開發規範之代碼格式篇(下)。
1.大括號換行
Alibaba規約(強制)
如果是大括號內爲空,則簡潔地寫成{}即可,大括號中間無需換行和空格;
如果是非空代碼塊則遵循下列規則:
- 左大括號前不換行。
- 左大括號後換行。
- 右大括號前換行。
- 右大括號後還有else等代碼則不換行;表示終止的右大括號後必須換行。
Google規約
對於非空塊和塊狀結構,大括號遵循Kernighan和Ritchie風格 (Egyptian brackets):
- 左大括號前不換行
- 左大括號後換行
- 右大括號前換行
- 如果右大括號是一個語句、函數體或類的終止,則右大括號後換行; 否則不換行。例如,如果右大括號後面是else或逗號,則不換行。
一個空的塊狀結構裏什麼也不包含,大括號可以簡潔地寫成 {} ,不需要換行。例外:如果它是一個多塊語句的一部分(if/else 或 try/catch/finally) ,即使大括號內沒內容,右大括號也要換行。
說明:大括號一般是函數、代碼塊和方法塊等整塊代碼作爲功能邏輯的標誌符號,因此整潔的代碼格式可以清楚瞭解代碼邏輯層次。
區別:兩個大廠的規約基本相同,Google規約說明更加詳細,Alibaba規約只列舉一個示例但也應該默認業界常用規範。
正例:
void doNothing() {} // 正例,代碼爲空,大括號簡寫
void doSomething(int flag) {
// 正例,左大括號後換行
if (flag == 1) {
System.out.println("world");
// 正例,右大括號前換行
} else { //正例,右大括號後有else,不用換行
System.out.println("ok");
// 正例,在右大括號後直接結束,則必須換行
}
}
try {
int result = 1 / 0;
System.out.println(result);
} catch (Exception e) { // 正例,右大括號後有catch, 代碼未結束,不用換行
// 正例,作爲try/catch/finally部分 ,即使大括號內沒內容,右大括號也要換行
} finally {
// 正例,finally部分 ,即使大括號內沒內容,右大括號也要換行,一般實際不這樣寫空代碼只作爲參考
}
反例:
// 反例,左括號不用換行,右括號如果內容爲空也不用換行
void doNothing()
{
}
// 反例,左括號不用換行,右括號如果代碼未結束也不用換行
void doSomething(int flag)
{
if (flag == 1)
{
System.out.println("world");
}
else
{
System.out.println("ok");
}
}
2.括號空格
Alibaba規約(強制)
- 左小括號和字符之間不出現空格,同樣,右小括號和字符之間也不出現空格;而左大括號前需要空格。
- if/for/while/switch/do等保留字與括號之間都必須加空格。
- 任何二目、三目運算符的左右兩邊都需要加一個空格。運算符包括賦值運算符=、邏輯運算符&&、加減乘除符號等。
Google規約
除了語言需求和其它規則,並且除了文字,註釋和Javadoc用到單個空格,單個ASCII空格也出現在以下幾個地方:
- 分隔任何保留字與緊隨其後的左括號( ( )(如 if, for catch 等)。
- 分隔任何保留字與其前面的右大括號( } )(如 else, catch )。
- 在任何左大括號前( { ),兩個例外:
- @SomeAnnotation({a, b}) (不使用空格)。
- String[][] x = foo; (大括號間沒有空格,見下面的Note)。
- 在任何二元或三元運算符的兩側。這也適用於以下“類運算符”符號:
- 類型界限中的&( <T extends Foo & Bar> )。
- catch塊中的管道符號( catch (FooException | BarException e )。
- foreach 語句中的分號。
- 類型和變量之間:List list。
- 數組初始化中,大括號內的空格是可選的,即 new int[] {5, 6} 和 new int[] { 5, 6} 都是可以的。
Note:這個規則並不要求或禁止一行的開關或結尾需要額外的空格,只對內部空格做要求。
說明:Google規約明確了空格使用場景,Google規約更加規範一些,部分規約條例已按照Alibaba規約拆分到其他條例,請繼續參考本文其他內容。
正例:
// 運算符左右兩邊需要空格
int flag = 1;
// 關鍵詞if與括號之間必須有一個空格,括號內的flag與左括號,0與右括號不需要空格,小括號和大括號之間有空格
if (flag == 0) {
System.out.println(say);
}
反例:
// 運算符兩側沒有空格
int flag=0;
// 關鍵詞if與括號沒有空格
if(flag == 0) {
System.out.println(flag);
}
// flag和左括號之間有空格,0和右括號之間有空格
if ( flag == 0 ) {
System.out.println(flag);
}
// 小括號和大括號之間無空格
if (flag == 0){
System.out.println(flag);
}
3.禁止tab字符
Alibaba規約(強制)
採用4個空格縮進,禁止使用tab字符。如果使用tab縮進,必須設置1個tab爲4個空格。IDEA設置tab爲4個空格時,請勿勾選Use tab character;而在eclipse中,必須勾選insert spaces for tabs。
Google規約
每當開始一個新的塊,縮進增加2個空格,當塊結束時,縮進返回先前的縮進級別。縮進級別適用於代碼和註釋。
說明:因爲tab縮進在不同的操作系統上或在不同的編輯器下顯示長短不一定,所以需要設置規則限制使用。IDEA設置tab參考路徑 File - Settings - Editor - Code Style - Java - Tabs and indents ,eclipse 設置tab參考路徑 Preferrence - Editor - Code Style - Text Editors 。
區別:Alibaba規約縮進採用4個空格,Google規約採用2個空格。個人感覺4個空格更美觀。
正例:
// 函數中代碼縮進4個空格
void doSomething() {
System.out.println();
}
反例:
// if語句中代碼塊未縮進
if (flag == 1){
System.out.println(flag);
}
4.註釋內容與雙斜線需一個空格
Alibaba規約(強制)
註釋的雙斜線與註釋內容之間有且僅有一個空格。
Google規約
如果在一條語句後做註釋,則雙斜槓(//)兩邊都要空格。這裏可以允許多個空格,但沒有必要。
說明:區分註釋內容和註釋符號。(單獨作爲一條規定感覺有點誇大影響???)
補充:注意函數註釋不能採用雙斜線行註釋,必須按照/**/註釋且標識參數,雙斜線註釋一般作用於變量註釋。
反例:
//這是示例註釋,雙斜線與註釋內容
String param = new String();
5.強制轉換時右括號與值不需要空格
Alibaba規約(強制)
在進行類型強制轉換時,右括號與強制轉換值之間不需要任何空格隔開。
Google規約
未定義類似規範
說明:強制轉換類型需要加小括號這時需要明確值,不使用空格可清晰辨識。
正例:
// 長整型符號L與數值無空格
long first = 1000000000000L;
// int類型符號的右括號與數值無空格
int second = (int)first + 2;
反例:
// Math.pow(2, 10)爲數值結果,int類型的右括號與它有空格
int result = (int) Math.pow(2, 10);