Google Java 編程風格指南

前言

香港彩票透码 www.kptln.icu 這份文檔是Google Java編程風格規范的完整定義。當且僅當一個Java源文件符合此文檔中的規則, 我們才認為它符合Google的Java編程風格。

與其它的編程風格指南一樣,這里所討論的不僅僅是編碼格式美不美觀的問題, 同時也討論一些約定及編碼標準。然而,這份文檔主要側重于我們所普遍遵循的規則, 對于那些不是明確強制要求的,我們盡量避免提供意見。

1.1 術語說明

在本文檔中,除非另有說明:

  1. 術語class可表示一個普通類,枚舉類,接口或是annotation類型(@interface)

  2. 術語comment只用來指代實現的注釋(implementation comments),我們不使用“documentation comments”一詞,而是用Javadoc。

其他的術語說明會偶爾在后面的文檔出現。

1.2 指南說明

本文檔中的示例代碼并不作為規范。也就是說,雖然示例代碼是遵循Google編程風格,但并不意味著這是展現這些代碼的唯一方式。 示例中的格式選擇不應該被強制定為規則。

源文件基礎

2.1 文件名

源文件以其最頂層的類名來命名,大小寫敏感,文件擴展名為.java。

2.2 文件編碼:UTF-8

源文件編碼格式為UTF-8。

2.3 特殊字符

2.3.1 空白字符

除了行結束符序列,ASCII水平空格字符(0×20,即空格)是源文件中唯一允許出現的空白字符,這意味著:

  1. 所有其它字符串中的空白字符都要進行轉義。

  2. 制表符不用于縮進。

2.3.2 特殊轉義序列

對于具有特殊轉義序列的任何字符(\b, \t, \n, \f, \r, \“, \‘及$$,我們使用它的轉義序列,而不是相應的八進制(比如12)或Unicode(比如\u000a)轉義。

2.3.3 非ASCII字符

對于剩余的非ASCII字符,是使用實際的Unicode字符(比如∞),還是使用等價的Unicode轉義符(比如\u221e),取決于哪個能讓代碼更易于閱讀和理解。

Tip: 在使用Unicode轉義符或是一些實際的Unicode字符時,建議做些注釋給出解釋,這有助于別人閱讀和理解。

例如:

String unitAbbrev = "μs";                                 | 贊,即使沒有注釋也非常清晰String unitAbbrev = "\u03bcs"; // "μs"                    | 允許,但沒有理由要這樣做String unitAbbrev = "\u03bcs"; // Greek letter mu, "s"    | 允許,但這樣做顯得笨拙還容易出錯String unitAbbrev = "\u03bcs";                            | 很糟,讀者根本看不出這是什么return '\ufeff' + content; // byte order mark             | Good,對于非打印字符,使用轉義,并在必要時寫上注釋

Tip: 永遠不要由于害怕某些程序可能無法正確處理非ASCII字符而讓你的代碼可讀性變差。當程序無法正確處理非ASCII字符時,它自然無法正確運行, 你就會去fix這些問題的了。(言下之意就是大膽去用非ASCII字符,如果真的有需要的話)

源文件結構

一個源文件包含(按順序地):

  1. 許可證或版權信息(如有需要)

  2. package語句

  3. import語句

  4. 一個頂級類(只有一個)

以上每個部分之間用一個空行隔開。

3.1 許可證或版權信息

如果一個文件包含許可證或版權信息,那么它應當被放在文件最前面。

3.2 package語句

package語句不換行,列限制(4.4節)并不適用于package語句。(即package語句寫在一行里)

3.3 import語句

3.3.1 import不要使用通配符

即,不要出現類似這樣的import語句:import java.util.*;

3.3.2 不要換行

import語句不換行,列限制(4.4節)并不適用于import語句。(每個import語句獨立成行)

3.3.3 順序和間距

import語句可分為以下幾組,按照這個順序,每組由一個空行分隔:

  1. 所有的靜態導入獨立成組

  2. com.google imports(僅當這個源文件是在com.google包下)

  3. 第三方的包。每個頂級包為一組,字典序。例如:android, com, junit, org, sun

  4. java imports

  5. javax imports

組內不空行,按字典序排列。

3.4 類聲明

3.4.1 只有一個頂級類聲明

每個頂級類都在一個與它同名的源文件中(當然,還包含.java后綴)。

例外:package-info.java,該文件中可沒有package-info類。

3.4.2 類成員順序

類的成員順序對易學性有很大的影響,但這也不存在唯一的通用法則。不同的類對成員的排序可能是不同的。 最重要的一點,每個類應該以某種邏輯去排序它的成員,維護者應該要能解釋這種排序邏輯。比如, 新的方法不能總是習慣性地添加到類的結尾,因為這樣就是按時間順序而非某種邏輯來排序的。

3.4.2.1 重載:永不分離

當一個類有多個構造函數,或是多個同名方法,這些函數/方法應該按順序出現在一起,中間不要放進其它函數/方法。

格式

術語說明:塊狀結構(block-like construct)指的是一個類,方法或構造函數的主體。需要注意的是,數組初始化中的初始值可被選擇性地視為塊狀結構(4.8.3.1節)。

4.1 大括號

4.1.1 使用大括號(即使是可選的)

大括號與if, else, for, do, while語句一起使用,即使只有一條語句(或是空),也應該把大括號寫上。

4.1.2 非空塊:K & R 風格

對于非空塊和塊狀結構,大括號遵循Kernighan和Ritchie風格 (Egyptian brackets):

  • 左大括號前不換行

  • 左大括號后換行

  • 右大括號前換行

  • 如果右大括號是一個語句、函數體或類的終止,則右大括號后換行; 否則不換行。例如,如果右大括號后面是else或逗號,則不換行。

示例:

return new MyClass() {  @Override public void method() {    if (condition()) {      try {
        something();
      } catch (ProblemException e) {
        recover();
      }
    }
  }
};

4.8.1節給出了enum類的一些例外。

4.1.3 空塊:可以用簡潔版本

一個空的塊狀結構里什么也不包含,大括號可以簡潔地寫成{},不需要換行。例外:如果它是一個多塊語句的一部分(if/else 或 try/catch/finally) ,即使大括號內沒內容,右大括號也要換行。

示例:

void doNothing() {}

4.2 塊縮進:2個空格

每當開始一個新的塊,縮進增加2個空格,當塊結束時,縮進返回先前的縮進級別。縮進級別適用于代碼和注釋。(見4.1.2節中的代碼示例)

4.3 一行一個語句

每個語句后要換行。

4.4 列限制:80或100

一個項目可以選擇一行80個字符或100個字符的列限制,除了下述例外,任何一行如果超過這個字符數限制,必須自動換行。

例外:

  1. 不可能滿足列限制的行(例如,Javadoc中的一個長URL,或是一個長的JSNI方法參考)。

  2. packageimport語句(見3.2節和3.3節)。

  3. 注釋中那些可能被剪切并粘貼到shell中的命令行。

4.5 自動換行

術語說明:一般情況下,一行長代碼為了避免超出列限制(80或100個字符)而被分為多行,我們稱之為自動換行(line-wrapping)。

我們并沒有全面,確定性的準則來決定在每一種情況下如何自動換行。很多時候,對于同一段代碼會有好幾種有效的自動換行方式。

Tip: 提取方法或局部變量可以在不換行的情況下解決代碼過長的問題(是合理縮短命名長度吧)

4.5.1 從哪里斷開

自動換行的基本準則是:更傾向于在更高的語法級別處斷開。

  1. 如果在非賦值運算符處斷開,那么在該符號前斷開(比如+,它將位于下一行)。注意:這一點與Google其它語言的編程風格不同(如C++和JavaScript)。 這條規則也適用于以下“類運算符”符號:點分隔符(.),類型界限中的&(<T extends Foo & Bar>),catch塊中的管道符號(catch (FooException | BarException e)

  2. 如果在賦值運算符處斷開,通常的做法是在該符號后斷開(比如=,它與前面的內容留在同一行)。這條規則也適用于foreach語句中的分號。

  3. 方法名或構造函數名與左括號留在同一行。

  4. 逗號(,)與其前面的內容留在同一行。

4.5.2 自動換行時縮進至少+4個空格

自動換行時,第一行后的每一行至少比第一行多縮進4個空格(注意:制表符不用于縮進。見2.3.1節)。

當存在連續自動換行時,縮進可能會多縮進不只4個空格(語法元素存在多級時)。一般而言,兩個連續行使用相同的縮進當且僅當它們開始于同級語法元素。

第4.6.3水平對齊一節中指出,不鼓勵使用可變數目的空格來對齊前面行的符號。

4.6 空白

4.6.1 垂直空白

以下情況需要使用一個空行:

  1. 類內連續的成員之間:字段,構造函數,方法,嵌套類,靜態初始化塊,實例初始化塊。

    • 例外:兩個連續字段之間的空行是可選的,用于字段的空行主要用來對字段進行邏輯分組。

  2. 在函數體內,語句的邏輯分組間使用空行。

  3. 類內的第一個成員前或最后一個成員后的空行是可選的(既不鼓勵也不反對這樣做,視個人喜好而定)。

  4. 要滿足本文檔中其他節的空行要求(比如3.3節:import語句)

多個連續的空行是允許的,但沒有必要這樣做(我們也不鼓勵這樣做)。

4.6.2 水平空白

除了語言需求和其它規則,并且除了文字,注釋和Javadoc用到單個空格,單個ASCII空格也出現在以下幾個地方:

  1. 分隔任何保留字與緊隨其后的左括號(()(如if, for catch等)。

  2. 分隔任何保留字與其前面的右大括號(})(如else, catch)。

  3. 在任何左大括號前({),兩個例外:

    • @SomeAnnotation({a, b})(不使用空格)。

    • String[][] x = foo;(大括號間沒有空格,見下面的Note)。

  4. 在任何二元或三元運算符的兩側。這也適用于以下“類運算符”符號:

    • 類型界限中的&(<T extends Foo & Bar>)。

    • catch塊中的管道符號(catch (FooException | BarException e)。

    • foreach語句中的分號。

  5. , : ;及右括號())后

  6. 如果在一條語句后做注釋,則雙斜杠(//)兩邊都要空格。這里可以允許多個空格,但沒有必要。

  7. 類型和變量之間:List list。

  8. 數組初始化中,大括號內的空格是可選的,即new int[] {5, 6}new int[] { 5, 6 }都是可以的。

Note:這個規則并不要求或禁止一行的開關或結尾需要額外的空格,只對內部空格做要求。

4.6.3 水平對齊:不做要求

術語說明:水平對齊指的是通過增加可變數量的空格來使某一行的字符與上一行的相應字符對齊。

這是允許的(而且在不少地方可以看到這樣的代碼),但Google編程風格對此不做要求。即使對于已經使用水平對齊的代碼,我們也不需要去保持這種風格。

以下示例先展示未對齊的代碼,然后是對齊的代碼:

private int x; // this is fineprivate Color color; // this tooprivate int   x;      // permitted, but future editsprivate Color color;  // may leave it unaligned

Tip:對齊可增加代碼可讀性,但它為日后的維護帶來問題??悸俏蠢茨掣鍪焙?,我們需要修改一堆對齊的代碼中的一行。 這可能導致原本很漂亮的對齊代碼變得錯位。很可能它會提示你調整周圍代碼的空白來使這一堆代碼重新水平對齊(比如程序員想保持這種水平對齊的風格), 這就會讓你做許多的無用功,增加了reviewer的工作并且可能導致更多的合并沖突。

4.7 用小括號來限定組:推薦

除非作者和reviewer都認為去掉小括號也不會使代碼被誤解,或是去掉小括號能讓代碼更易于閱讀,否則我們不應該去掉小括號。 我們沒有理由假設讀者能記住整個Java運算符優先級表。

4.8 具體結構

4.8.1 枚舉類

枚舉常量間用逗號隔開,換行可選。

沒有方法和文檔的枚舉類可寫成數組初始化的格式:

private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }

由于枚舉類也是一個類,因此所有適用于其它類的格式規則也適用于枚舉類。

4.8.2 變量聲明

4.8.2.1 每次只聲明一個變量

不要使用組合聲明,比如int a, b;。

4.8.2.2 需要時才聲明,并盡快進行初始化

不要在一個代碼塊的開頭把局部變量一次性都聲明了(這是c語言的做法),而是在第一次需要使用它時才聲明。 局部變量在聲明時最好就進行初始化,或者聲明后盡快進行初始化。

4.8.3 數組

4.8.3.1 數組初始化:可寫成塊狀結構

數組初始化可以寫成塊狀結構,比如,下面的寫法都是OK的:

new int[] {  0, 1, 2, 3 }new int[] {  0,  1,  2,  3}new int[] {  0, 1,  2, 3}new int[]
    {0, 1, 2, 3}
4.8.3.2 非C風格的數組聲明

中括號是類型的一部分:String[] args, 而非String args[]。

4.8.4 switch語句

術語說明:switch塊的大括號內是一個或多個語句組。每個語句組包含一個或多個switch標簽(case FOO:default:),后面跟著一條或多條語句。

4.8.4.1 縮進

與其它塊狀結構一致,switch塊中的內容縮進為2個空格。

每個switch標簽后新起一行,再縮進2個空格,寫下一條或多條語句。

4.8.4.2 Fall-through:注釋

在一個switch塊內,每個語句組要么通過break, continue, return或拋出異常來終止,要么通過一條注釋來說明程序將繼續執行到下一個語句組, 任何能表達這個意思的注釋都是OK的(典型的是用// fall through)。這個特殊的注釋并不需要在最后一個語句組(一般是default)中出現。示例:

switch (input) {  case 1:  case 2:
    prepareOneOrTwo();    // fall through
  case 3:
    handleOneTwoOrThree();    break;  default:
    handleLargeNumber(input);
}
4.8.4.3 default的情況要寫出來

每個switch語句都包含一個default語句組,即使它什么代碼也不包含。

4.8.5 注解(Annotations)

注解緊跟在文檔塊后面,應用于類、方法和構造函數,一個注解獨占一行。這些換行不屬于自動換行(第4.5節,自動換行),因此縮進級別不變。例如:

@[email protected] String getNameIfPresent() { ... }

例外:單個的注解可以和簽名的第一行出現在同一行。例如:

@Override public int hashCode() { ... }

應用于字段的注解緊隨文檔塊出現,應用于字段的多個注解允許與字段出現在同一行。例如:

@Partial @Mock DataLoader loader;

參數和局部變量注解沒有特定規則。

4.8.6 注釋

4.8.6.1 塊注釋風格

塊注釋與其周圍的代碼在同一縮進級別。它們可以是/* ... */風格,也可以是// ...風格。對于多行的/* ... */注釋,后續行必須從*開始, 并且與前一行的*對齊。以下示例注釋都是OK的。

/*
 * This is          // And so           /* Or you can
 * okay.            // is this.          * even do this. */
 */

注釋不要封閉在由星號或其它字符繪制的框架里。

Tip:在寫多行注釋時,如果你希望在必要時能重新換行(即注釋像段落風格一樣),那么使用/* ... */。

4.8.7 Modifiers

類和成員的modifiers如果存在,則按Java語言規范中推薦的順序出現。

public protected private abstract static final transient volatile synchronized native strictfp

via:碼農網

上一篇: 關于日志記錄的一些感想

下一篇: Java 8的新特性—終極版

分享到: 更多
彩票挂机真的稳赚吗 北京pk10直播官方网站 七乐彩最近50期走势图 ag软件挂机打公式自动投注 百家乐技巧规律软件 90k0极速比分足球比分 分分快三技巧规律 pk10怎么玩法介绍 11选53胆拖5多少钱 四川时时走势图开奖结果查询 360竞彩混合投注 云南时时走势20选5走势图 电子游戏注册大全 七星彩最容易中奖方法 下载麻将游戏免费四人 彩票网上投注平台pk10