# JAVA 语言编码规范

## 4.1 命名规范
### 规则1.1(强制)
标识符由字母、数字、下划线和美元符（$）组成，不能包含@、%和空格等特殊字符，不能以下划线、数字或美元符号开始或结束，不能是Java关键字，区分大小写。

### 规则1.2(强制)
各种命名应使用正确的英文拼写和语法，避免拼音、混合拼写、不规范缩写、中文命名。

### 规则1.3(强制)
包名统一小写，点分隔符间一个自然语义单词，词意从大到小，前缀顶级域名，项目包名以com.psbc.开头。

### 规则1.4(强制)
类名使用UpperCamelCase命名方式，简洁且富于描述。

### 规则1.5(建议)
抽象类命名建议Abstract开头，异常类Exception结尾，测试类Test结尾，设计模式体现于类名。

### 规则1.6(强制)
方法名使用lowerCamelCase命名方式。

### 规则1.7(强制)
常量命名全大写，单词间下划线隔开，语义完整清楚。

### 规则1.8(建议)
布尔类型实例变量命名不使用is前缀。

### 规则1.9(强制)
参数名、实例变量、局部变量使用lowerCamelCase命名方式。

### 规则1.10(强制)
类型与中括号紧挨表示数组。

### 规则1.11(强制)
避免子父类成员变量、不同代码块局部变量相同命名。

### 规则1.12(建议)
自定义编程元素命名尽量完整单词组合。

### 规则1.13(建议)
常量、变量命名表示类型名词放词尾。

### 规则1.14(建议)
接口类方法、属性不加修饰符号，简洁并加Javadoc注释，接口少定义变量。

### 规则1.15(强制)
Service和DAO类基于SOA理念，暴露服务是接口，内部实现类用Impl后缀。

### 规则1.16(建议)
形容词接口名用形容词，如–able结尾。

### 规则1.17(建议)
枚举类名带Enum后缀，成员名称全大写，单词间下划线隔开。

### 规则1.18(建议)
a) Service/DAO层方法命名：
  1）获取单个对象用get前缀；
  2）获取多个对象用list前缀，复数结尾；
  3）获取统计值用count前缀；
  4）插入用save/insert前缀；
  5）删除用remove/delete前缀；
  6）修改用update前缀。
b) 领域模型命名：
  1）领域对象以xxxDO/DTO/VO命名；
  2）避免以POJO结尾实体对象或值对象命名。

## 4.2 格式规范
### 规则2.1(强制)
源文件编码UTF-8，Unix换行符。

### 规则2.2(建议)
除注释外，方法签名等总行数不超过80行。

### 规则2.3(强制)
类文件组成部分顺序：文件头注释、包引入、类声明、常量、变量、构造函数、方法。

### 规则2.4(建议)
多个构造函数或同名方法应顺序在一起。

### 规则2.5(建议)
方法按功能而非作用域或访问权限分组。

### 规则2.6(强制)
引用类时禁止用*引入包全部类，避免无用、重复引用，不import java.lang和同包类。

### 规则2.7(强制)
Java关键字正确顺序：public、protected、private、abstract、static、final、transient、volatile、synchronized、native。

### 规则2.8(建议)
避免多余关键字，接口方法属性不加修饰符号。

### 规则2.9(强制)
每行至多一条语句。

### 规则2.10(强制)
大括号使用约定：
a）左大括号前不换行；
b）左大括号后换行；
c）右大括号前换行；
d）右大括号后有else等代码不换行，终止后必须换行；
e）大括号内为空，简洁写成{}，不换行。

### 规则2.11(建议)
缩进采用4个空格，多行变量声明赋值不强制等号对齐，tab设为4空格宽度。

### 规则2.12(建议)
单行字符数不超过120，换行原则：
a）第二行相对第一行缩进4空格，第三行起不再缩进；
b）运算符与下文换行；
c）点符号与下文换行；
d）方法调用参数多需换行时，在逗号后换行；
e）括号前不换行。

### 规则2.13(建议)
用空行分隔逻辑相关代码段，提高可读性，不插入多个空行。

## 4.3 注释规范
### 规则3.1(建议)
类、属性、方法注释使用Javadoc格式。

### 规则3.2(强制)
公共API代码必须编写JavaDoc注释，类、属性、方法、参数、返回值、异常全部注释。

## 4.4 常量变量
### 规则4.1(建议)
避免使用魔法数，应定义为常量。

### 规则4.2(强制)
长整型常量后使用大写字母“L”。

### 规则4.3(建议)
浮点数类型数值后缀统一为大写D或F。

### 规则4.4(建议)
按功能或模块归类常量。

### 规则4.5(建议)
常量复用层次分为五层：跨应用、应用内、子工程内、包内、类内。

### 规则4.6(建议)
变量值在固定范围变化时用enum类型。

### 规则4.7(强制)
每行只声明一个变量。

### 规则4.8(建议)
局部变量声明时初始化。

### 规则4.9(强制)
避免一个语句中给多个变量赋相同值，不用内嵌赋值运算符。

### 规则4.10(强制)
避免局部变量覆盖上一级变量。

### 规则4.11(强制)
数组类型变量声明采用数据类型[]的方式。

## 4.5 控制语句
### 规则5.1(强制)
switch括号内为String且为外部参数时，先进行null判断。

### 规则5.2(强制)
每个switch语句包含default分支，且default在最后。

### 规则5.3(强制)
if/else/for/while/do语句中必须使用大括号。

### 规则5.4(建议)
避免不可达的else if和else分支。

### 规则5.5(强制)
条件表达式尽量简化。

### 规则5.6(建议)
返回表达式尽量简化。

### 规则5.7(建议)
避免在循环中重复执行相同内容。

### 规则5.8(建议)
慎用非短路逻辑运算符。

### 规则5.9(建议)
含多种运算符的表达式中使用圆括号。

### 规则5.10(建议)
三元运算符前的表达式需加圆括号。

### 规则5.11(建议)
复杂条件判断结果赋值给布尔变量。

## 4.6 面向对象
### 规则6.1(强制)
禁止用类的实例对象引用访问静态变量或方法。

### 规则6.2(强制)
覆写方法必须加@Override注解。

### 规则6.3(强制)
覆写equals必须覆写hashCode。

### 规则6.4(建议)
过时接口或方法加@Deprecated注解。

### 规则6.5(建议)
避免使用过时类或方法。

### 规则6.6(建议)
慎用可变参数编程。

### 规则6.7(建议)
用常量或确定有值的对象调用equals。

### 规则6.8(建议)
参数个数相同的方法重载时，避免用自动转换类型，建议用不同方法名。

### 规则6.9(建议)
使用final关键字的情况：
a）不允许继承的类；
b）不允许修改引用的域对象；
c）不允许重写的方法；
d）不允许重新赋值的局部变量；
e）避免重复使用变量。

### 规则6.10(建议)
慎用Object的clone方法。

### 规则6.11(强制)
类成员变量访问控制从严。

### 规则6.12(建议)
类方法访问控制从严。

### 规则6.13(强制)
构造方法中避免处理业务逻辑，初始化逻辑放init方法。

### 规则6.14(强制)
RPC方法返回值和参数用包装类型。

### 规则6.15(建议)
局部变量用基本类型。

### 规则6.16(建议)
POJO类不设定属性默认值。

### 规则6.17(强制)
POJO类必须写toString方法。

### 规则6.18(强制)
POJO类禁止同时存在isXxx和getXxx方法。

### 规则6.19(建议)
setter中参数名与成员变量名一致，this.成员名=参数名。getter/setter中不加业务逻辑。

### 规则6.20(强制)
序列化类新增属性时不修改serialVersionUID，不兼容升级时修改。

## 4.7 数值计算
### 规则7.1(强制)
比较字符串用equals，不用==或!=。

### 规则7.2(强制)
避免自动类型转换导致溢出或精度丢失。

### 规则7.3(建议)
避免高精度转低精度溢出。

### 规则7.4(强制)
禁止用BigDecimal(double)构造，用String构造或valueOf。

### 规则7.5(强制)
精确计算用BigDecimal，不用浮点数。

### 规则7.6(强制)
与NaN比较用isNaN()，不用==或!=。

### 规则7.7(强制)
自增自减运算符使用要产生实际影响。

### 规则7.8(强制)
BigDecimal比较用compareTo，不用equals。

### 规则7.9(强制)
SimpleDateFormat非线程安全，不用在并发环境。JDK8及以上用DateTimeFormatter。

### 规则7.10(强制)
日期格式化Pattern统一规范。

### 规则7.11(建议)
三目运算符注意类型对齐可能引发空指针。

## 4.8 集合规范
### 规则8.1(建议)
慎用ArrayList.subList。

### 规则8.2(建议)
慎用Arrays.asList。

### 规则8.3(强制)
集合转数组用toArray(T[] array)，传入长度为0的空数组。

### 规则8.4(强制)
禁止集合中添加自身。

### 规则8.5(强制)
foreach循环中不做remove/add操作，用Iterator。

### 规则8.6(建议)
参照常用Map集合K/V存储null情况。

### 规则8.7(建议)
合理利用集合的有序性和稳定性。

### 规则8.8(强制)
集合明确泛型。

### 规则8.9(建议)
判断集合元素是否为空用isEmpty，不用size()==0。

### 规则8.10(强制)
toMap()方法必须用带mergeFunction的。

### 规则8.11(强制)
toMap()方法中value为NULL时处理。

### 规则8.12(强制)
不可对keySet()/values()/entrySet()返回集合做增删。

### 规则8.13(强制)
排序时Comparator要满足三个条件。

## 4.9 线程安全
### 规则9.1(建议)
单例获取保证线程安全，推荐饿汉模式。

### 规则9.2(建议)
并发访问的单例禁止有状态成员变量。

### 规则9.3(建议)
创建线程或线程池指定有意义名称。

### 规则9.4(建议)
多个资源加锁保持一致顺序。

### 规则9.5(强制)
CountDownLatch使用确保countDown被执行。

### 规则9.6(强制)
锁在finally中释放。

### 规则9.7(强制)
同步代码中不用public属性。

### 规则9.8(强制)
占用锁时不调用Thread.sleep。

### 规则9.9(建议)
并发场景用线程安全集合。

### 规则9.10(强制)
线程资源通过线程池提供，不显式创建。

### 规则9.11(建议)
线程池用ThreadPoolExecutor，不用Executors。

### 规则9.12(建议)
高并发避免用“等于”判断，用区间判断。

## 4.10 异常处理
### 规则10.1(强制)
可通过预检查避免的RuntimeException不捕获。

### 规则10.2(建议)
不用异常做流程控制。

### 规则10.3(建议)
finally中不使用return。

### 规则10.4(强制)
非稳定代码catch区分异常类型。

### 规则10.5(强制)
捕获异常要处理，不抛弃，最外层业务使用者处理异常。

### 规则10.6(强制)
try在事务代码中，catch后手动回滚事务。

### 规则10.7(强制)
finally中关闭资源，JDK7+用try-with-resources。

### 规则10.8(建议)
捕获与抛出异常类型匹配。

### 规则10.9(建议)
捕获异常区分Exception和Error。

## 4.11 日志规范
### 规则11.1(强制)
应用用日志框架（SLF4J）API，不用直接用Log4j、Logback API。

### 规则11.2(强制)
禁止用System.out.print等方法，用标准日志框架。

### 规则11.3(建议)
日志用占位符，不用“+”拼接。

### 规则11.4(建议)
日志级别分为FATAL、ERROR、WARN、INFO、DEBUG，各级别使用建议。

### 规则11.5(建议)
info/debug日志进行开关判断。

### 规则11.6(强制)
日志中用户敏感信息脱敏。

### 规则11.7(建议)
日志打印参数中避免复杂表达式。

## 4.12 性能相关
### 规则13.1(建议)
同步调用优先用无锁数据结构，锁代码块尽可能小。

### 规则13.2(建议)
避免频繁创建可复用资源。

### 规则13.3(建议)
避免创建不必要的对象。

### 规则13.4(建议)
避免变量重复计算。

### 规则13.5(建议)
try/catch放在循环外层。

### 规则13.6(建议)
池化重量级资源。

### 规则13.7(建议)
遍历Map用entrySet，JDK8+用Map.foreach。

### 规则13.8(建议)
用Set去重，不用List的contains。

### 规则13.9(建议)
慎用递归，必须时保证出口可执行。

### 规则13.10(建议)
用观察者模式替换无限轮询。

### 规则13.11(建议)
缓存不常变化数据。

### 规则13.12(建议)
字符串拼接用StringBuilder或StringBuffer。

### 规则13.13(建议)
数组拷贝用System.arraycopy。

### 规则13.14(建议)
合理使用单例。

### 规则13.15(建议)
避免随意用静态变量。

### 规则13.16(建议)
未发生线程安全时用HashMap、ArrayList。

### 规则13.17(建议)
避免用二维数组。

### 规则13.18(建议)
合理使用线性表和链表。

### 规则13.19(建议)
避免非常大的内存分配。

### 规则13.20(建议)
正则表达式编译后复用。