0%

Google Java编程规范

本博文是对《Google Java Style Guide》的阅读笔记,由于在对IDE进行一番配置(参见“对IDE的具体配置”)后,执行Reformat Code命令能够使得自动遵循很多编程规范,因此,接下来只列出需要手动遵循的编程规范。

对IDE的具体配置:
1、使用的IDE为:IntelliJ IDEA
2、从链接处下载“intellij-java-google-style.xml”配置文件
3、选择“Settings–Editor–Code Style–Java”导入“intellij-java-google-style.xml”配置文件
4、勾选“Code–Show Reformat File Dialog”中“Optimize Imports”和“Rearrange Code”两个选项

一、源文件

1.1、源文件名

源文件名由“源文件中主类类名”和“.java扩展名”构成。

1.2、源文件编码格式

使用UTF-8编码格式。

1.3、字符

1.3.1、空白字符[2]

源文件中不能包含除了“换行符和空格字符(0x20)”之外的其他空白字符。
这个具有两层含义:

  • 作为控制和修饰用途的“其他空白字符”不允许被使用。比如不允许出现“Tab字符(按下Tab键)”
  • 作为实际有意义内容组成部分的“其他空白字符”不允许以“直接形式”被使用,而只能以或者“转义序列”,或者“八进制转义序列”,或者“Unicode转义序列”形式被使用。比如“\t”

1.3.2、字符表达形式优先级

字符表达形式有:直接形式(比如“a”),转义序列形式(比如“\b”),八进制转义序列形式(比如“\012”),Unicode转义序列形式(比如“\u000a”)。每个字符所具有的表达形式是不定的。在源文件中,尝试表达字符时,在该字符所具有的表达形式中依次按照“直接形式,转义序列形式,(八进制转义序列形式,Unicode转义序列形式)”的顺序选取最终表达形式。假如最终表达形式非“直接形式”,那么需添加注释进行说明。
示例如下:

1
2
3
String unitAbbrev = "\t"; // Tab字符
String unitAbbrev = "μs";
return '\ufeff' + content; // byte order mark

二、源文件文件结构

1、源文件中依次包括4部分内容:版权信息(可选),package语句(可选),import语句(可选),主类定义
2、使用import语句导入类A的静态内部类B时,使用import A.B形式,而不使用import static A.B形式
3、重载方法需被置于一起,中间不包含任何其他内容(对于“重载的构造方法”,执行Reformat Code命令时,“重载的构造方法被置于一起”会被自动遵循)

三、格式化

3.1、运算表达式中的括号

在运算表达式中,尽量通过添加()括号对的形式提升运算顺序的可读性。

3.2、变量定义

1、每行只定义一个变量,禁止类似int a, b形式
2、对于局部变量来说,只在即将需要用到的时候进行局部变量的定义,而不要提前很多进行,从而减小局部变量的作用域
3、定义数组类型变量时,采用类似String[] args形式,禁止使用类似String args[]形式,因为类似String[]才是真正的数组类型

3.3、switch语句

switch语句中具有“块”的概念,“块”是指:一个或者多个分支语句(“case”或者“default”语句)进入同一个执行逻辑,这些分支语句连同上述的执行逻辑被称为一个“块”,比如下面展现的就是一个“块”。

1
2
3
case 1:
case 2:
prepareOneOrTwo();

1、在switch语句中,必须包含“default”分支语句
2、在switch语句中,“块”的结束方式必须是且只能是下述5种方式之一:“break”,“continue”,“return”,“throw exception”和“// fall through注释语句(该注释语句声明继续执行进入下一个‘块’,但当处于最后‘块’中时,该注释语句可被省略)”
示例如下:

1
2
3
4
5
6
7
8
9
10
11
switch (input) {
case 1:
case 2:
prepareOneOrTwo();
// fall through
case 3:
handleOneTwoOrThree();
break;
default:
handleLargeNumber(input);
}

3.4、注解

当同时存在注解与JavaDoc时,注解应置于JavaDoc之后。

3.5、修饰符

Java修饰符的排列顺序应该按照如下顺序:

1
public protected private abstract default static final transient volatile synchronized native strictfp

3.6、长整型字面量

在表达一个长整型字面量时,使用L后缀,禁止使用l后缀。
示例如下:

1
2
Long a = 10000L;
long b = 10000L;

四、命名

所有Java标识符都由“大写英文字母,小写英文字母,数字和下划线”构成,即JDK正则表达式中“\w”所表达的字符范围。
大驼峰命名法:由1个或者多个单词构成,只允许包含“大写英文字母,小写英文字母,数字”,其中大写英文字母只允许在每个单词的首字符位置出现。
小驼峰命名法:由1个或者多个单词构成,只允许包含“大写英文字母,小写英文字母,数字”,其中大写英文字母只允许在每个单词(除了第一个单词)的首字符位置出现。

4.1、包名

多个部分以“.”字符连接构成,而每个部分又由“小写英文字母和数字”构成。

4.2、类名

采用“大驼峰命名法”。
1、“具体类,抽象类,枚举类”的类名一般是“名词词组”;“接口”的类名一般是“名词词组”,也可以是“形容词词组”;“注解类”的类名没有特定规范
2、测试类的类名是在被测试类的类名之后加上“Test”后缀
示例如下:

1
2
3
4
5
6
7
8
class ArrayLis {}
interface List {}
interface Readable {}

// ---分隔---

class CodeUtil {}
class CodeUtilTest {}

4.3、方法名

采用“小驼峰命名法”,一般是动词词组。测试方法的名称没有特定规范。

4.4、常量成员变量名称

由“大写英文字母,数字,下划线”构成,一般是名词词组。
“常量成员变量”定义:
1、由“static final”修饰符组合修饰的成员变量
2、成员变量的类型一般为“基本类型,String类型,不可变类型,元素为不可变类型的不可变集合类型”,更准确的描述是:一旦该成员变量定义完成,使得“包括该成员变量值所在内存区域在内,加上所有级联到内存区域”中的值都不再改变的类型都可作为该成员变量的类型
3、根据“枚举类”的定义,其中所有的“枚举值”实质上都是特殊的“常量成员变量名称”
示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Constants
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);
static final Joiner COMMA_JOINER = Joiner.on(','); // com.google.common.base.Joiner , Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }

// Not constants
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"};

4.5、非常量成员变量名称

采用“小驼峰命名法”,一般是名词词组。

4.6、方法参数变量名称

采用“小驼峰命名法”,一般是名词词组,禁止只包含1个字符的名称。

4.7、局部变量名称

采用“小驼峰命名法”,一般是名词词组。

4.8、泛型体系中类型参数名称

泛型体系中类型参数名称有两种形式:1)一个大写英文字母,加上一个可选的数字;2)相应的类名加上“T”字母。
示例如下:

1
2
3
4
5
6
7
8
9
10
public class Request<T> {}

public class Request<RequestT> {}

public class Request<T1> {

public static <K, V> Map<K, V> map() {

}
}

五、编程实践

5.1、使用@Override注解

出现覆盖情形时,使用@Override注解。

5.2、处理Caught Exception

在“try-catch-finally”语句块的“catch语句”中,必须对异常进行处理:或者打印日志,或者重新抛出异常,或者进行注释说明。
示例如下:

1
2
3
4
5
6
7
8
9
try {

} catch (AException a) {
logger.error("", a);
} catch (BException b) {
throw new Exception(b);
} catch (CException c) {
// c exception is impossible
}

另外,如果是在测试方法中,且“catch语句”对应的异常是被期望的异常,那么可将该异常命名为“expected”或者以“expected”为前缀,而无需再在该“catch语句”中对该异常进行处理。
示例如下:

1
2
3
4
5
try {
emptyStack.pop();
fail();
} catch (NoSuchElementException expected) {
}

5.3、使用类引用类的静态成员

使用类引用类的静态成员,禁止使用类的实例引用类的静态成员。

5.4、禁止依赖Object类的finalize()方法

禁止依赖Object类的finalize()方法。

六、JavaDoc

1、对于类的成员,除非意义明显,否则都应该加上JavaDoc
2、每个JavaDoc都应该有一段文字描述
3、JavaDoc中,用<p>标签来分隔多段文字描述内容,多段文字描述内容之间以一行空格进行隔开
示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* <p>first thing
*
* <p>second thing
*
* <p>third thing
*
* @return return the result
*/
public String doSomething() {

}

参考文献: [1]https://google.github.io/styleguide/javaguide.html [2]https://en.wikipedia.org/wiki/Whitespace_character
您的支持将鼓励我继续分享!