1.命名
规则1.1 源文件编码格式(包括注释)必须是UTF-8,ASCII水平空格字符(0x20,即空格)是唯一允许出现的空白字符,制表符不用于缩进
规则1.2 所有标识符仅使用ASCII字母和数字,名称由正则表达式匹配 \w{2,64}
规则1.3 包名称小写以点号隔开,自研代码以com.xxx开头,包名允许有数字
规则1.4 类、枚举和接口名称采用首字母大写的驼峰命名法
规则1.5 方法名称采用首字母小写的驼峰命名法
规则1.6 常量名称全大写单词以下划线分隔
规则1.7 非常量字段名称采用首字母小写的驼峰命名法
建议1.1 避免使用否定的布尔变量名
2.注释 规则2.1 Javadoc用于每一个public或protected修饰的元素
规则2.2 对于方法有参数、返回值、异常等信息时,必须在Javadoc块中描述:功能、@param、@return、@throws等。
规则2.3 Javadoc标签与内容间只1个空格,按@param,@return,@throws顺序排列
规则2.4 文件头注释必须包含版权许可,顶层public类头有功能说明、创建日期
规则2.5 禁止空有格式的方法头注释
规则2.6 注释正文与其下的各个Javadoc tag之间加1个空行;类级成员注释与上面的代码之间有一个空行;注释符与注释内容间要有1空格;右置注释与前面代码至少1空格
规则2.7 不用的代码段直接删除,不要注释掉
建议2.1 正式交付给客户的代码不能包含TODO/FIXME 注释
3.排版格式 规则3.1 避免文件过长,不超过2000行(非空非注释行)
规则3.2 一个源文件按顺序包含版权、package、import、顶层类,且用空行分隔
规则3.3 在条件语句和循环块中必须使用大括号
规则3.4 对于非空块和块状结构,左大括号放在行尾
规则3.5 使用空格进行缩进,每次缩进4个空格
规则3.6 换行起点在点号、双冒号、类型&、catch块中管道之前,在方法左括号、逗号、lambda箭头和其左大括号之后
规则3.7 每行声明一个变量
规则3.8 禁止C风格的数组声明
规则3.9 case语句块结束时如果不加break,需要有注释说明(fall-through)
规则3.10 switch语句要有default分支,除非switch的条件变量是枚举类型
规则3.11 数字字面量以大写字母为后缀
建议3.2 一个类或接口的声明部分应当按照类变量、实例变量、构造器、方法的顺序出现,且用空行分隔
建议3.3 应该避免空块;多块的右大括号应该新起一行
建议3.4 每行不超过一个语句
建议3.5 每行限长120个窄字符
建议3.6 减少不必要的空行,保持代码紧凑
建议3.7 单个空格应该分隔关键字与其后的左括号、与其前面的右大括号,出现在任何二元/三元运算符/类似运算符的两侧,,:;或类型转换结束括号)之后使用空格。行末和空行不能有空格space
建议3.8 不应插入空格水平对齐
建议3.9 枚举常量间用逗号隔开,换行可选
建议3.10 变量被声明在接近它们首次使用的行
建议3.11 应用于类,方法或构造方法的每个注解独占一行
建议3.12 类和成员修饰符(如果存在)按Java语言规范建议的顺序显示
4.变量和类型 规则4.1 不能用浮点数作为循环变量
规则4.2 需要精确计算时不要使用float和double
规则4.3 浮点型数据判断相等不能直接使用==
规则4.4 禁止尝试与NaN进行比较运算,相等操作使用Double或Float的isNaN方法
规则4.5 不要在单个的表达式中对相同的变量赋值超过一次
建议4.1 在向下类型转换前用instanceof进行判断
5.方法 规则5.1 避免方法过长,不超过50行(非空非注释)
规则5.2 避免方法的代码块嵌套过深,不要超过4层
规则5.3 使用类名调用静态方法,而不要使用实例或表达式来调用
建议5.1 不要把方法的入参当做工作变量/临时变量
建议5.2 方法的参数个数不应超过5个
建议5.3 谨慎使用可变数量参数的方法
建议5.4 构造方法如果参数较多,尽量重用
建议5.5 对于返回数组或者容器的方法,应返回长度为0的数组或者容器,代替返回null
6.类和接口 规则6.1 避免在无关的变量或无关的概念之间重用名字,避免隐藏(hide)、遮蔽(shadow)和遮掩(obscure)
规则6.2 不要在父类的构造方法中调用可能被子类覆写的方法
规则6.3 覆写equals方法时,应同时覆写hashCode方法
规则6.4 子类覆写父类方法时应加上@Override注解
建议6.3 接口定义中去掉多余的修饰词
7.异常和日志 规则7.1 不要通过一个空的catch块忽略异常
规则7.2 方法抛出的异常,应该与本身的抽象层次相对应
规则7.3 在finally块中不要使用return、break或continue使finally块非正常结束
规则7.4 日志的记录,不要使用 System.out 与 System.err 进行控制台打印,进行处理应使用Facade模式的日志框架(例如:产品自研的,或第三方Slf4j等)
规则7.5 日志工具Logger类的实例应声明为private static final
规则7.6 日志应分等级,对info及以下,使用条件形式或者使用占位符的方式
规则7.7 非仅限于中文区销售产品禁止用中文打印日志
建议7.1 不要直接捕获受检异常的基类Exception
建议7.2 一个方法不应抛出超过5个异常,并在Javadoc的@throws标签中记录每个抛出的异常及其条件
8.编程实践 规则8.1.1 避免数据竟争data race
规则8.1.2 创建新线程时需指定线程名
规则8.1.3 使用Thread对象的setUncaughtExceptionHandler方法注册Runtime异常处理者
规则8.1.4 不要依赖线程调度器、线程优先级和yield()方法
规则8.1.5 采用Java1.5提供新并发工具代替wait()和notify()
规则8.3.1 不要在控制性条件表达式中执行赋值
规则8.3.2 不要在foreach循环里进行元素的 remove/add 操作,删除元素请使用removeIf方法或Iterator
规则8.4.1 序列化对象中的HashMap、HashSet或HashTable等集合不能包含对象自身的引用
规则8.6.1 不要使用已标注为@deprecated的方法
规则8.7.1 将集合转为数组时使用toArray()方法且参数是类型相同零长度的数组
规则8.7.2 避免创建不必要的对象
规则8.7.4 需要在同一函数内获取和关闭的资源(如IO类资源),应使用try-with-resource或在finally里关闭
规则8.7.5 禁止使用主动GC(除非在密码、RMI等方面),尤其是在频繁/周期性的逻辑中
规则8.7.6 禁止使用finalize()方法
规则8.8.1 不要在代码中硬编码"\n"和"\r"作为换行符号
规则8.9.1 在所有的输入输出环节,指明正确的编码方式,进行正确的字符到字节,或字节到字符的转换
规则8.9.2 不要依赖平台默认的字符编码方式,使用UTF-8
规则8.9.3 字符串大小写转换、数字格式化为西方数字时,必须加上Locale.ROOT或Locale.ENGLISH
建议8.1.1 线程打断由业务代码来协作完成,慎用Thread.interrupt方法
建议8.1.2 避免不加控制地创建新线程,而应该使用线程池来管控资源
建议8.2.1 用括号明确表达式的操作顺序,避免过分依赖默认优先级
建议8.2.3 表达式的比较,应当遵循左侧倾向于变化、右侧倾向于不变的原则
建议8.3.1 对于if-else if(后续可能有多个else if)类型的条件判断,最后应该包含一个else分支。
建议8.4.1 尽量不要实现Serializable接口
建议8.4.2 实现Serializable接口的可序列化类应该显式声明 serialVersionUID
建议8.4.3 不应序列化直接指向系统资源的句柄
建议8.5.1 尽量消除非受检的异常,不应该在整个类上使用SuppressWarnning
建议8.5.2 方法的设计可优先考虑泛型
建议8.5.3 优先使用泛型集合,而不是数组
建议8.5.4 声明一个泛型类通过限定符限制可用的泛型类型
建议8.6.2 Java 8使用Optional代替null作为返回值或者可能的缺失值
建议8.6.3 避免枚举常量序号的产生依赖于ordinal()方法