Google开源项目风格指南——Java

Google Java Style Guide

谷歌 Java 风格指南

谷歌 Java 风格指南

1 简介

本文档是Google Java™ 编程语言源代码编码标准的完整定义。当且仅当Java 源文件遵守此处的规则时,才将其描述为Google 风格。

与其他编程风格指南一样,所涵盖的问题不仅涵盖格式的美观问题,还涵盖其他类型的约定或编码标准。然而,本文档主要关注我们普遍遵循的硬性规则,并避免提供无法明确执行的 建议(无论是人类还是工具)。

1.1 术语说明

在本文档中,除非另有说明:

  1. 术语 用于表示“普通”类、枚举类、接口或注解类型 ( @interface)。
  2. 术语 成员 (一个类的)包括嵌套类、字段、方法或构造函数;也就是说,一个类的所有顶层内容,初始化项和注释除外。
  3. 术语 注释 始终指的是 实现 注释。我们不使用短语“文档注释”,而是使用通用术语“Javadoc”。

其他 “术语说明” 偶尔会出现在整个文件中。

1.2 指导说明

本文档中的示例代码是非规范的。也就是说,虽然这些示例采用 Google 风格,但它们可能无法说明表示代码的 唯一 时尚方式。示例中所做的可选格式选择不应作为规则强制执行。

2 源文件基础知识

2.1 文件名

源文件名由它包含的顶级类的区分大小写的名称(正好有一个),以及 .java扩展名组成。

2.2 文件编码:UTF-8

源文件以UTF-8编码。

2.3 特殊字符

2.3.1 空白字符

除了行终止符序列之外,ASCII 水平空格字符( 0x20 ) 是唯一出现在源文件中任何位置的空白字符。这意味着:

  1. 字符串和字符文本中的所有其他空白字符都会被转义。
  2. 制表符用于缩进。
2.3.2 特殊转义序列

对于具有 特殊转义序列\b\t\n\f\r\"\'\\ )的字符,都会使用该序列,而不是相应的八进制(例如\012)或 Unicode(例如\u000a)转义。

2.3.3 非ASCII字符

对于其余的非 ASCII 字符, 使用实际的 Unicode 字符(例如 )或等效的 Unicode 转义符(例如 \u221e )。尽管强烈建议不要在字符串文字和注释之外进行 Unicode 转义,但选择仅取决于哪个使代码更易于阅读和理解。

**提示:**在 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好:对不可打印的字符使用转义符,并在必要时进行注释。

提示:永远不要仅仅因为担心某些程序可能无法正确处理非 ASCII 字符而降低代码的可读性。如果发生这种情况,那么这些程序就被破坏了,必须修复它们。

3 源文件结构

源文件按顺序包含:

  1. 许可证或版权信息(如果存在)
  2. package语句
  3. import语句
  4. 正好是一个顶级类

恰好有一个空行分隔存在的每个部分。

3.1 许可或版权信息(如果存在)

如果许可证或版权信息属于某个文件,则它属于此处。

3.2 封装声明

package 语句是不换行的。列限制(第 4.4 节, 列限制: 100)不适package语句。

3.3 导入语句

3.3.1 禁止通配符导入)

不使用静态或其他形式的通配符导入

3.3.2 不换行

导入语句是不换行的。列限制(第 4.4 节, 列限制: 100)不适用于 import 语句。

3.3.3 顺序和间距

import顺序如下:

  1. 所有静态导入都在一个块中。
  2. 所有非静态导入都在一个块中。

如果同时存在静态和非静态导入,则用一个空行分隔两个块。 import 语句之间没有其他空行。

在每个块中,导入的名称按 ASCII 排序顺序显示。 (**注意:**这与导入语句的ASCII排序顺序不同,因为 . 之前排序。)

3.3.4 类不能静态导入

静态导入不用于静态嵌套类。它们是通过正常进口进口的。

3.4 类声明

3.4.1 恰好一个顶级类声明

每个顶级类都驻留在其自己的源文件中。

3.4.2 class内容的排序

您为类的成员和初始化器选择的顺序会对可读性产生很大影响。然而,对于如何进行排序并没有一个固定的正确方案;不同的类可能会根据各自的方式对其内容进行不同的排序。

重要的是,每个类都应该遵循某种逻辑顺序,当被问及时,维护者能够对此进行解释。例如,不应习惯性地将新方法追加到类的末尾,因为这样会导致“按照添加日期顺序排列”的结果,这并非逻辑上的排序方式。理想的排序方式应基于如功能相关性、访问权限或依赖关系等逻辑准则来组织类的内部结构。

3.4.2.1 重载:不可分散

类中具有相同名称的方法应排列成一个连续的整体,其间不允许插入其他类型的成员。同样的规则也适用于多个构造函数(它们的名称总是相同的)。即使这些方法之间的 staticprivate 等修饰符不同,这条规则仍然适用。

4 格式化

术语说明: 类块构造是指类、方法或构造函数的主体。请注意,根据有关 数组初始值设定项的第 4.8.3.1 节,任何数组初始值设定项都 可以选择性地被视为类似块的构造。

4.1 大括号

4.1.1 可选大括号的使用

即使条件语句或循环体为空,或者只包含一个单行语句,也应该在 if、else、for、dowhile 等语句中使用花括号(大括号)。

其他可选的大括号,如lambda表达式中的大括号,仍然是可选的。

4.1.2 非空块:K & R 风格

对于非空块和块状结构,大括号遵循 Kernighan 和 Ritchie 风格 (“埃及括号”)

  • 左大括号之前没有换行符,除非下面有详细说明。
  • 左大括号后换行。
  • 右大括号之前换行。
  • 仅当 该大括号终止语句或终止方法、构造函数或命名 类的主体时,在右大括号后换行。例如,如果大括号后跟 else 或 逗号,则大括号后不会换行

例外:在这些规则允许单个语句以分号 ( ;) 结尾的地方,可以出现语句块,并且该语句块的左大括号前面有一个换行符。通常引入此类块来限制局部变量的范围,例如在 switch 语句内。

例子:

return () -> {
  while (condition()) {
    method();
  }
};

return new MyClass() {
  @Override public void method() {
    if (condition()) {
      try {
        something();
      } catch (ProblemException e) {
        recover();
      }
    } else if (otherCondition()) {
      somethingElse();
    } else {
      lastThing();
    }
    {
      int x = foo();
      frob(x);
    }
  }
};

枚举类的一些例外情况在第4.8.1节“ Enum classes”中给出。

4.1.3 空块:可能简洁

空块或类块构造可以是 K & R 样式(如 第 4.1.2 节中所述)。或者,它可以在打开后立即关闭,之间没有字符或换行符 ( {}),除非它是多块语句的一部分 (直接包含多个块的语句: if/elsetry/catch/finally)。

例子:

// 这是可以接受的
void doNothing() {}

// 这同样可以接受
void doNothingElse() {
}

// 这是不可接受的:多块语句中没有简洁的空块
try {
	doSomething();
} catch (Exception e) {}

4.2 块缩进:+2个空格

每次打开新的块或类似块的构造时,缩进都会增加两个空格。当块结束时,缩进返回到先前的缩进级别。缩进级别适用于整个块中的代码和注释。 (请参阅第 4.1.2 节,非空块:K & R 样式中的示例 。)

4.3 每行一条语句

每个语句后面都有一个换行符。

4.4 列数限制:100

Java 代码的列限制为 100 个字符。 “字符”是指任何 Unicode 代码点。除非下面另有说明,否则任何超出此限制的行都必须换行,如第 4.5 节“换行”中所述。

每个 Unicode 代码点都算作一个字符,即使其显示宽度更大或更小。例如,如果使用 全角字符,您可以选择早于此规则严格要求的位置换行。

例外情况:

  1. 不可能遵守列限制的行(例如,Javadoc 中的长 URL 或长 JSNI 方法引用)。
  2. packageimport语句(参见 3.2包语句和 3.3导入语句)。
  3. 注释中的命令行可以复制并粘贴到 shell 中。
  4. 非常长的标识符(在极少数需要的情况下)允许超出列限制。在这种情况下,周围代码的有效包装由google-java-format生成 。

4.5 换行

**术语注释:**当原本可能合法占用单行的代码被分成多行时,此活动称为 换行

没有一个全面的、确定性的公式可以准确地说明如何在每种情况下换行。通常有几种有效的方法可以对同一段代码进行换行。

**注意:**虽然换行的典型原因是避免溢出列限制,但即使实际上适合列限制的代码也可以 由作者自行决定进行换行。

**提示:**提取方法或局部变量可能会解决问题,而无需换行。

4.5.1 在哪里中断

换行的主要指令是:更喜欢在 更高的语法级别中断。还:

  1. 当一行在非赋值运算符处断行时,断点出现在符号之前。(请注意,这与 Google 风格中用于其他语言(例如 C++ 和 JavaScript)的做法不同。)

    • 这也适用于以下“类似运算符”的符号:
      • 点分隔符 ( .)
      • 方法引用的两个冒号 ( ::)
      • 类型绑定中的 & 符号 ( <T extends Foo & Bar>)
      • catch块 ( ) 中的管道catch (FooException | BarException e)
  2. 当一行在赋值运算符处断行时,断行通常出现在符号 之后,但无论哪种方式都是可以接受的。

    • 这也适用于增强 for(“foreach”)语句中的“类似赋值运算符”冒号。
  3. 方法或构造函数名称保留附加到其后面的左括号 (

  4. 逗号 ( ,) 与其前面的标记保持关联。

  5. lambda 中与箭头相邻的行永远不会断开,但如果 lambda 主体由单个无括号表达式组成,则可能会在箭头之后立即出现断开。例子:

    MyLambda<String, Long, Object> lambda =
        (String label, Long value, Object obj) -> {
            ...
        };
    
    Predicate<String> predicate = str ->
        longExpressionInvolving(str);
    

**注意:**换行的主要目标是拥有清晰的代码,而不一定是适合最少行数的代码。

4.5.2 连续行缩进至少+4个空格

换行时,第一行之后的每一行(每个连续行)都比原始行缩进至少+4。

当有多个连续行时,缩进可以根据需要变化超过 +4。一般来说,当且仅当两条连续行以语法上平行的元素开头时,它们才使用相同的缩进级别。

关于水平对齐的第 4.6.3 节解决了不鼓励使用可变数量的空格来将某些标记与前一行对齐的做法。

4.6 空白

4.6.1 垂直空白

总是出现一个空行:

  1. 类的连续成员或初始值设定项 之间:字段、构造函数、方法、嵌套类、静态初始值设定项和实例初始值设定项。

    • **例外:**两个连续字段之间的空行(它们之间没有其他代码)是可选的。根据需要使用此类空行来创建字段的逻辑分组
    • **例外:**枚举常量之间的空行在第 4.8.1 节中介绍。
  2. 按照本文档其他部分的要求(例如第 3 节 “源文件结构”和第 3.3 节 “导入语句”)。

单个空行也可以出现在任何可以提高可读性的地方,例如在将代码组织成逻辑小节的语句之间。既不鼓励也不鼓励在类的第一个成员或初始化程序之前或最后一个成员或初始化程序之后使用空行。

允许有多个连续的空行,但从不要求(或鼓励)。

4.6.2 水平空白

除了语言或其他样式规则要求的地方之外,除了文字、注释和 Javadoc 之外,单个 ASCII 空格也仅出现在以下位置

  1. 将任何保留字(例如 iffor或 )与其后面的该行上的catch左括号 ( ) 分隔开(

  2. 将任何保留字(例如 elseor )与其前面的catch右花括号 ( ) 分隔开}

  3. 在任何左大括号 ( {) 之前,但有两个例外:

    • @SomeAnnotation({a, b})(不使用任何空间)
    • String[][] x = {{"foo"}};``{{(下面第 9 项中的之间不需要空格)
  4. 在任何二元或三元运算符的两侧。这也适用于以下“类似运算符”的符号:

    • 连接类型绑定中的 & 符号: <T extends Foo & Bar>
    • 处理多个异常的 catch 块的管道: catch (FooException | BarException e)
    • :增强型 for(“foreach”)语句中的冒号 ( )
    • lambda 表达式中的箭头: (String str) -> str.length()

    但不是

    • 方法引用的两个冒号 ( ::),写法如下Object::toString
    • 点分隔符 ( .),写法如下 object.toString()
  5. ,:;在强制转换的右括号 ( ))之后

  6. //在任何内容和开始注释的双斜杠 ( ) 之间。允许有多个空格。

  7. 位于开始注释的双斜杠 ( //) 和注释文本之间。允许有多个空格。

  8. 在声明的类型和变量之间: List<String> list

  9. 在数组初始值设定项的两个大括号内 是可选的

    • new int[] {5, 6}并且 new int[] { 5, 6 }都是有效的
  10. 在类型注释和[]or 之间...

此规则决不会被解释为要求或禁止在行首或行尾添加额外空格;它仅涉及内部空间。

4.6.3 水平对齐:不需要

术语说明: 水平对齐 是在代码中添加可变数量的附加空格的做法,目的是使某些标记直接出现在前一行中某些其他标记的下方。

这种做法是允许的,但Google Style从来不要求这样做。甚至不需要在已经使用过的地方保持水平对齐。

这是一个没有对齐的示例,然后使用对齐:

private int x; // // 这是很好的
private Color color; // 这也是

private int   x;      // 允许,但将来修改
private Color color;  // 可能会使其不对齐

提示:对齐可以提高可读性,但会给将来的维护带来问题。考虑一下未来只需要触及一行的更改。此更改可能会破坏以前令人满意的格式,但这是允许的。更多时候,它会提示编码器(也许是您)也调整附近行上的空白,可能会触发一系列级联的重新格式化。这一行的改变现在有了一个“爆炸半径”。在最坏的情况下,这可能会导致无意义的忙碌工作,但在最好的情况下,它仍然会破坏版本历史信息,减慢审阅者的速度并加剧合并冲突。

4.7 分组括号:推荐

仅当作者和审阅者一致认为如果没有可选的分组括号,代码不会被误解,也不会使代码更易于阅读,则可以省略可选的分组括号。假设每个读者都记住整个 Java 运算符优先级表是不合理的。

4.8 具体构造

4.8.1 枚举类

在枚举常量后面的每个逗号之后,换行符是可选的。还允许添加额外的空行(通常只有一个)。这是一种可能性:

private enum Answer {
  YES {
    @Override public String toString() {
      return "yes";
    }
  },

  NO,
  MAYBE
}

没有方法且没有常量文档的枚举类可以选择将其格式化为数组初始值设定项(请参阅第 4.8.3.1 节有关 数组初始值设定项的内容)。

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

由于枚举类是类,因此格式化类的所有其他规则都适用。

4.8.2 变量声明
4.8.2.1 每个声明一个变量

每个变量声明(字段或局部)仅声明一个变量: int a, b;不使用诸如此类的声明。

**例外:**循环头中可以接受多个变量声明 for

4.8.2.2 需要时声明

局部变量通常不会在其包含块或类块构造的开头声明。相反,局部变量是在它们第一次使用的地方附近声明的(在合理范围内),以最小化它们的范围。局部变量声明通常具有初始值设定项,或者在声明后立即初始化。

4.8.3 数组
4.8.3.1 数组初始值设定项:可以是“块状”

任何数组初始值设定项都可以选择格式化为“类似块的构造”。例如,以下内容都是有效的(不是详尽的列表):

new int[] {           new int[] {
  0, 1, 2, 3            0,
}                       1,
                        2,
new int[] {             3,
  0, 1,               }
  2, 3
}                     new int[]
                          {0, 1, 2, 3}
4.8.3.2 无 C 风格数组声明

方括号构成类型的一部分,而不是变量: String[] args, 不是 String args[]

4.8.4 Switch语句

术语注释: switch 块的大括号内 是一个或多个语句组*。每个语句组由一个或多个开关标签( 或case FOO:) 组成default:,后跟一个或多个语句(或者,对于最后一个语句组,*零个或多个语句)。

4.8.4.1 缩进

与任何其他块一样,switch 块的内容缩进 +2。

在开关标签之后,有一个换行符,并且缩进级别增加 +2,就像打开一个块一样。下面的开关标签返回到之前的缩进级别,就像一个块已被关闭一样。

4.8.4.2 失败:已注释

在 switch 块中,每个语句组要么突然终止(带有 breakcontinuereturn抛出异常),要么用注释标记以指示执行将或可能继续到下一个语句组。任何传达失败想法的评论就足够了(通常 // fall through)。 switch 块的最后一个语句组中不需要此特殊注释。例子:

switch (input) {
  case 1:
  case 2:
    prepareOneOrTwo();
    // fall through
  case 3:
    handleOneTwoOrThree();
    break;
  default:
    handleLargeNumber(input);
}

请注意,之后不需要任何注释case 1:,只需在语句组的末尾。

default4.8.4.3标签的存在

每个 switch 语句都包含一个default语句组,即使它不包含任何代码。

**例外:如果enum类型的 switch 语句包含涵盖该类型的所有可能值的显式情况,则该类型的 switch 语句可以省略语句组。这使得 IDE 或其他静态分析工具能够在遗漏任何情况时发出警告。 default

4.8.5 注解
4.8.5.1 类型使用注解

类型使用注释紧邻带注释的类型之前出现。如果注释使用元注释,则该注释类型使用注释 @Target(ElementType.TYPE_USE)。例子:

final @Nullable String name;

public @Nullable Person getPersonByName(String name);
4.8.5.2 类注解

应用于类的注释立即出现在文档块之后,并且每个注释都在其自己的一行中列出(即,每行一个注释)。这些换行符不构成换行(第 4.5 节,换行),因此不会增加缩进级别。例子:

@Deprecated
@CheckReturnValue
public final class Frozzler { ... }
4.8.5.3 方法和构造函数注解

方法和构造函数声明上的注释规则与上一节相同 。例子:

@Deprecated
@Override
public String getNameIfPresent() { ... }

**例外:单个无参数注释 *可能会与*签名的第一行一起出现,例如:

@Override public int hashCode() { ... }
4.8.5.4 字段注解

应用于字段的注释也会立即出现在文档块之后,但在这种情况下,多个注释(可能是参数化的)可能会列在同一行上;例如:

@Partial @Mock DataLoader loader;
4.8.5.5 参数和局部变量注解

对于参数或局部变量的注释格式没有特定的规则(当然,当注释是类型使用注释时除外)。

4.8.6 注释

本节讨论实施意见。 Javadoc 在第 7 节Javadoc中单独讨论。

任何换行符前面都可以有任意空格,后跟实现注释。这样的注释使得该行非空白。

4.8.6.1 块注释样式

块注释与周围代码的缩进级别相同。它们可能是 /* ... */风格或 // ...风格。对于多行 /* ... */注释,后续行必须 与前一行*对齐。*

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

注释不包含在用星号或其他字符绘制的框中。

**提示:**编写多行注释时, /* ... */如果您希望自动代码格式化程序在必要时重新换行(段落样式),请使用该样式。大多数格式化程序不会在 // ...样式注释块中重新换行。

4.8.7 修饰符

类和成员修饰符(如果存在)按 Java 语言规范推荐的顺序出现:

public protected private abstract default static final transient volatile synchronized native strictfp
4.8.8 数字文字

long-值整数文字使用大写L后缀,切勿使用小写(以避免与 digital 混淆1)。例如,3000000000L 而不是30000000001.

5 命名

5.1 所有标识符通用的规则

标识符仅使用 ASCII 字母和数字,并且在下面提到的少数情况下使用下划线。因此,每个有效的标识符名称都与正则表达式匹配 \w+

在Google Style中,不使用特殊的前缀或后缀。例如,这些名称不是 Google 风格:name_mName和 。s_name``kName

5.2 按标识符类型划分的规则

5.2.1 包名

包名称仅使用小写字母和数字(无下划线)。连续的单词只是连接在一起。例如,com.example.deepspace、 不 com.example.deepSpacecom.example.deep_space

5.2.2 类名

类名以UpperCamelCase书写。

类名通常是名词或名词短语。例如, CharacterImmutableList。接口名称也可以是名词或名词短语(例如,List),但有时也可以是形容词或形容词短语(例如, Readable)。

命名注释类型没有特定的规则,甚至没有既定的约定。

测试类名称以 结尾Test,例如HashIntegrationTest。如果它涵盖单个类,则其名称是该类的名称加上Test,例如HashImplTest

5.2.3 方法名称

方法名称以小驼峰命名法编写。

方法名称通常是动词或动词短语。例如, sendMessagestop

JUnit测试方法名称中可能会出现下划线,以分隔名称的逻辑组件,例如,每个组件都以小驼峰命名法编写transferMoney_deductsFromSource。没有一种正确的方法来命名测试方法。

5.2.4 常量名称

常量名称使用UPPER_SNAKE_CASE: 全部大写字母,每个单词与下一个单词之间用一个下划线分隔。但常数到底是什么?

常量是静态最终字段,其内容是深度不可变的,并且其方法没有可检测到的副作用。示例包括基元、字符串、不可变值类以及任何设置为null.如果实例的任何可观察状态可以改变,那么它就不是常量。仅仅打算永远不改变对象是不够的。例子:

// 常量
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final Map<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);
static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};

// 非常量
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final Set<String> mutableCollection = new HashSet<String>();
static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
static final ImmutableMap<String, SomeMutableType> mutableValues =
    ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};

这些名称通常是名词或名词短语。

5.2.5 非常量字段名称

非常量字段名称(静态或其他)以小驼峰命名法编写。

这些名称通常是名词或名词短语。例如, computedValuesindex

5.2.6 参数名称

参数名称以小驼峰命名法编写。

应避免在公共方法中使用单字符参数名称。

5.2.7 局部变量名

局部变量名以小驼峰命名法书写。

即使是最终且不可变的,局部变量也不被视为常量,也不应被设计为常量。

5.2.8 类型变量名

每个类型变量都以两种样式之一命名:

  • 单个大写字母,可选后跟单个数字(例如 E, T, X, T2
  • 用于类的形式的名称(请参阅第 5.2.2 节, 类名),后跟大写字母 T(例如: RequestT, FooBarT)。

5.3 驼峰案例:定义

有时,有不止一种合理的方法可以将英语短语转换为驼峰式大小写,例如当出现首字母缩略词或不常见的结构(例如“IPv6”或“iOS”)时。为了提高可预测性,Google Style 指定了以下(几乎)确定性方案。

从名字的散文形式开始:

  1. 将短语转换为纯 ASCII 并删除所有撇号。例如,“Müller 算法”可能会变为“Muellers 算法”。

  2. 将此结果分成单词,按空格和任何剩余的标点符号(通常是连字符)进行分割。

    • 建议:如果任何单词在常见用法中已经具有传统的驼峰式外观,请将其拆分为其组成部分(例如,“AdWords”变为“广告词”)。请注意,诸如“iOS”之类的单词本身并不是真正的驼峰式大小写;它违反了任何 惯例,因此该建议不适用。
  3. 现在将所有内容(包括首字母缩略词)小写,然后仅将以下字符的第一个字符大写:

    • …每个单词,产生大驼峰式大小写,或者
    • …除了第一个之外的每个单词,以产生小驼峰式大小写
  4. 最后,将所有单词连接成一个标识符。

请注意,原始单词的大小写几乎完全被忽略。例子:

散文形式正确的不正确
“XML HTTP 请求”XmlHttpRequestXMLHTTPRequest
“新客户 ID”newCustomerIdnewCustomerID
《内在秒表》innerStopwatchinnerStopWatch
“iOS 上支持 IPv6 吗?”supportsIpv6OnIossupportsIPv6OnIOS
“YouTube 导入程序”YouTubeImporter YoutubeImporter*

*可以接受,但不推荐。

**注意:**某些单词在英语中连字符不明确:例如“nonempty”和“non-empty”都是正确的,因此方法名称 checkNonemptycheckNonEmpty同样都是正确的。

6 编程实践

6.1 @Override:始终使用

@Override只要方法合法,就会用注释来标记该方法。这包括重写超类方法的类方法、实现接口方法的类方法以及重新指定超接口方法的接口方法。

例外: @Override当父方法是 时可以省略 @Deprecated

6.2 捕获异常:不忽略

除了下面指出的情况外,对捕获的异常不采取任何措施的情况很少是正确的。 (典型的响应是记录它,或者如果它被认为“不可能”,则将其重新抛出为 AssertionError。)

当确实适合在 catch 块中不采取任何操作时,注释中会解释其合理性的原因。

try {
  int i = Integer.parseInt(response);
  return handleNumericResponse(i);
} catch (NumberFormatException ok) {
  // it's not numeric; that's fine, just continue
}
return handleTextResponse(response);

例外:在测试代码中,如果捕获的异常名称是或以“expected”开头,那么可以无需注释就直接忽略该异常。以下是一种非常常见的用于确保被测试代码确实抛出了预期类型的异常的惯用法,在这种情况下,添加注释通常是不必要的。

try {
  emptyStack.pop();
  fail();
} catch (NoSuchElementException expected) {
}

6.3 静态成员:使用类限定

当必须限定对静态类成员的引用时,应使用该类的名称来限定它,而不是使用该类类型的引用或表达式。

Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad

6.4 终结器:不使用

重写Object.finalize罕见的

**提示:**不要这样做。如果您绝对必须这样做,请首先仔细阅读并理解 Effective Java Item 8 ,非常谨慎“避免终结器和清理器”,然后就不要样做。

7 Javadoc

7.1 格式化

7.1.1 一般形式

Javadoc 块的基本格式如下例所示:

/**
 * 这里写了多行Javadoc文本,
 * 正常换行... 
 */
public int method(String p1) { ... }

…或者在这个单行示例中:

/** 一段特别短的 Javadoc。  */

基本形式总是可以接受的。当整个 Javadoc 块(包括注释标记)可以放在一行上时,可以替换单行形式。请注意,这仅适用于没有块标签例如@return.

7.1.2 段落

一个空行(即仅包含对齐的前导星号 ( *) 的行)出现在段落之间以及块标记组(如果存在)之前。除第一个段落外,每个段落的第<p>一个单词之前都紧邻,之后没有空格。其他块级元素的 HTML 标记(例如<ul><table>)前面带有<p>

7.1.3 块标签

在Java文档注释中,如果使用标准的块标签(block tags),它们应按照以下顺序出现:@param、@return、@throws和@deprecated。这四种类型的标签都必须带有非空的描述内容,即不能留空。当某个块标签的内容无法单行显示时,延续行应当从“@”符号所在位置向内缩进四个(或更多)空格进行对齐。

7.2 摘要片段

每个 Javadoc 块都以一个简短的摘要片段开头。该片段非常重要:它是文本中出现在某些上下文(例如类和方法索引)中的唯一部分。

这是一个片段——名词短语或动词短语,而不是完整的句子。它不是 , A {@code Foo} is a...or 开头 This method returns...,也不是像 那样构成完整的祈使句Save the record.。然而,该片段是大写的并标点符号,就好像它是一个完整的句子一样。

**提示:**一个常见的错误是在表单中编写简单的 Javadoc /** @return the customer ID */。这是不正确的,应该更改为 /** Returns the customer ID. */

7.3 Javadoc的使用场合

至少,对于每一个公共类(public class),以及此类中的每一个公共成员(public)或受保护成员(protected),都应提供Javadoc注释,以下面列出的一些例外情况除外。

还可能存在其他 Javadoc 内容,如第 7.3.4 节“ 非必需 Javadoc”中所述。

7.3.1 例外:不言自明的成员

对于“简单、明显”的成员如 getFoo(),Javadoc 是可选的,在这种情况下,除了“返回 foo”之外*,确实* 没有什么值得说的。

**重要提示:**引用此例外来证明省略典型读者可能需要了解的相关信息是不合适的。例如,对于名为 的方法,如果典型读者可能不知道术语“规范名称”的含义,getCanonicalName请不要省略其文档(其基本原理是仅表示 )!/** Returns the canonical name. */

7.3.2 例外:覆盖

Javadoc 并不总是出现在重写超类型方法的方法上。

7.3.4 非必需的 Javadoc

其他类和成员根据需要或期望具有 Javadoc 。

每当使用实现注释来定义类或成员的总体目的或行为时,该注释都会被编写为 Javadoc(使用/**)。

非必需 Javadoc 并不严格要求遵循第 7.1.1、7.1.2、7.1.3 和 7.2 节的格式规则,但当然建议这样做。

  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值