2. Tigase代码样式

2.1. 介绍

本文档定义并描述了Tigase项目源代码中使用的编码风格和标准。

示例应被视为 非规范,即格式选择不应被视为规则。

2.2. 源文件基础

2.2.1. 技术细节

  • 文件名由它包含的顶级类的区分大小写的驼峰式名称加上 .java 扩展名组成。

  • 源文件以 UTF-8 编码。

2.3. 源文件结构

源文件包括, 按顺序

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

  2. 包装声明

  3. 导入语句

  4. 正是一个顶级类

此外:

  • 正好一个空行 分隔第 2-4 节;

  • package 声明是 非自动换行 (列限制不适用);

2.3.1. 导入语句

  • 通配符导入可用于:

    • 多于5个类导入;

    • 超过3个名称导入;

  • import 语句 不是自动换行 (列限制不适用);

  • 以下导入顺序适用:

    • 所有不属于下列任何组的导入

    • blank line

    • javax.*

    • java.*

    • blank line

    • 单个块中的所有静态导入

  • 每个块中的项目按名称按 ASCII 排序顺序排序(因为 ; 排序在 . 之前)

2.3.2. 类声明

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

类内容顺序

以下类元素的顺序是强制性的:

  • final, static 字段按以下顺序:

    • public

    • protected

    • package-private

    • private

  • public enum

  • static 字段按以下顺序:

    • public

    • protected

    • package-private

    • private

  • static 初始化程序块

  • final 字段按以下顺序:

    • public

    • protected

    • package-private

    • private

  • 没有修饰符的字段按以下顺序:

    • public

    • protected

    • package-private

    • private

  • 初始化程序块

  • static 方法

  • 构造函数

  • 没有修饰符的方法

  • 没有修饰符的枚举

  • 没有修饰符的接口

  • 内部 static

  • 内部类

此外:

  • Getter和Setter保持在一起

  • 超载永远不会拆分 - 具有相同名称的多个构造函数或方法按顺序出现。

2.4. 格式化

2.4.1. 大括号

  • 在可选情况下大括号是强制性的 - 对于使用大括号的所有语法都是可选的,即使主体为空或仅包含单个语句,Tigase也要求使用大括号。

  • 大括号遵循 Kernighan 和 Ritchie 样式 (Egyptian brackets):

    • 在左大括号之前没有换行符。

    • 左大括号后的换行符。

    • 右大括号之前的换行符。

    • 右大括号后的换行符,仅当 该大括号用于终止语句或终止方法,构造函数或 named 类的主体。例如,如果大括号后跟 else 或逗号,则大括号后有 no 换行符。

2.4.2. 块缩进:制表符

所有缩进(打开一个新的块状结构块)必须使用制表符进行。在块之后,然后缩进返回到前一个。

理想制表符个数:4

2.4.3. 列限制:120

定义的列限制为 120 个字符,并且必须按如下所述进行换行, Java 代码的列限制为 100 个字符。除下文所述外,任何超出此限制的行都必须换行,如 Line-wrapping 部分所述。

2.4.4. 换行

换行 是一个分割长行的过程,否则会超过定义的列限制(如上所述)。建议尽可能换行,即使它们不超过定义的限制。

2.4.5. 空白

垂直空白

出现一个空行:

  • 在包声明后;

  • 在导入之前;

  • 导入之后;

  • 围绕类;

  • 在类标头之后;

  • 围绕接口中的字段;

  • 围绕接口中的方法;

  • 围绕方法;

  • 围绕初始化器;

  • 根据本文档其他部分的要求。

不允许有多个空行。

水平空白

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

  1. 任何保留字,例如 if, for, while, switch, try, catchsynchronized, 与来自该行后面的左括号 (() 分开

  2. 将任何保留字,例如 elsecatch,与该行之前的右花括号 (}) 分开

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

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

    • **String[][] x = {{"foo"}};{{ 之间不需要空格,根据下面的第 8 项)

  4. 在任何二元或三元运算符的两侧。这也适用于以下 ‘’类似运算’’ 的符号:

    • 合取类型界限中的 & 符号: <T extends Foo & Bar>

    • 处理多个异常的 catch 块的管线: catch (FooException | BarException e)

    • 增强的 for (“foreach”) 语句中的冒号 (:)

    • lambda 表达式中的箭头:(String str) str.length()

      但不是:

    • 方法引用的两个冒号(::),写成 Object::toString

    • 点分隔符(.),写成 object.toString()

  5. ,:; 或右括号 (``)``) 之后

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

水平对齐:从不需要

水平对齐 是在代码中添加可变数量的附加空格的做法,目的是使某些令牌直接出现在前几行的某些其他令牌下方。

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

2.4.6. 具体构造

枚举类

在枚举常量后面的每个逗号之后,必须有一个换行符。

变量声明

  • 每个声明一个变量 - 每个变量声明(字段或本地)只声明一个变量:不使用诸如 int a, b; 之类的声明。

  • 在需要时声明 - 局部变量 习惯性地在其包含块或类似块的构造的开头声明。相反,局部变量在接近它们首次使用的点(在合理范围内)的时候被声明,以最小化它们的范围。局部变量声明通常具有初始化器,或者在声明后立即初始化。

数组

任何数组初始值设定项都可以 可选地 被格式化,就好像它是一个 “类似块的构造” (特别是当需要应用换行时)。

2.5. 命名

2.5.1. 所有标识符通用的规则

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

标识符类型的特定规则

  • 包的名称都是小写的,连续的单词简单地连接在一起(没有下划线,不是驼峰式)。

  • 类名用 UpperCamelCase 书写。

  • 方法名称以 lowerCamelCase 书写。

  • 常量名称使用 CONSTANT_CASE:全部大写字母,单词之间用下划线分隔。

  • 非常量字段名称(静态或其他)以 lowerCamelCase 编写。

  • 参数名称以 lowerCamelCase 书写(应避免在公共方法中使用单字符参数名称)。

  • 局部变量名称以 lowerCamelCase 书写。

2.6. 编程实践

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

  • 不应忽略抓到的异常(如果这是必须的,则需要日志条目)。

2.7. Javadoc

  • 空行应插入:

    • 描述,

    • 参数说明,

    • 返回标签;

  • 以下标签应包含空标签:

    • @params

    • @return

    • @throws

2.7.1. 用法

最低限度,Javadoc 存在于每个 public 类,以及此类的每个 publicprotected 成员,但有一些例外:

  • 对于像 getFoo 这样的 简单和明显 的方法是可选的,在这种情况下,真正的 除了”返回 foo”之外没有什么值得说的。

  • 在覆盖超类型方法的方法中。