java开发规范个人精简
根据自己的经验进行适当提炼重要的,需要的.
阅读中。。。。
编程规约
命名风格
-
类名首字母大骆驼拼写法。方法、参数、变量名小骆驼拼写法
LeiMing bianLiang fangFa(),canShu
-
常量命名全大写,单词用下划线隔开
final satic int MAX_SIZE =100;
-
抽象类命名使用 Abstract 或 Base 开头
-
命名时尽量完整且不与父子类或者不同代码块的局部变量之间采用完全相同的命名
-
包名统一小写,
.
之间有且仅有一个自然语义的单词 -
接口类中的方法和属性不要加任何修饰符号(public 也不要加)
-
对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部的实现类用Impl 的后缀与接口区别。
CacheServiceImpl 实现 CacheService 接口
-
枚举类名带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。
枚举名字为 ProcessStatusEnum 的成员名称:SUCCESS / UNKNOWN_REASON。
-
Service/DAO层命名规约(参考mybatis-plus的文档)
- 获取单个对象的方法用 get 做前缀
int getById(int uid)
-
获取多个对象的方法用 list 做前缀,复数结尾
List
list(); Collection
listByMap(Map<String, Object> columnMap); -
获取统计值的方法用 count 做前缀
int count();
-
插入的方法用 save/insert 做前缀
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(CollectionentityList); -
删除的方法用 remove/delete 做前缀
// 根据 entity 条件,删除记录 boolean remove(Wrapper<T> queryWrapper); // 根据 ID 删除 boolean removeById(Serializable id); // 根据 columnMap 条件,删除记录 boolean removeByMap(Map<String, Object> columnMap);
-
修改的方法用 update 做前缀。
-
在 long 或者 Long 赋值时,数值后使用大写的 L,不能是小写的 l
代码格式
-
任何二目、三目运算符的左右两边都需要加一个空格
-
左小括号和右边相邻字符之间不出现空格
反例 :if (
空格
a == b空格
)正例 : if (flag == 0)
-
采用 4 个空格缩进,禁止使用 tab 字符
-
书中样例
public static void main(String[] args) {
// 缩进 4 个空格
String say = "hello";
// 运算符的左右必须有一个空格
int flag = 0;
// 关键词 if 与括号之间必须有一个空格,括号内的 f 与左括号,0 与右括号不需要空格
if (flag == 0) {
System.out.println(say);
}
// 左大括号前加空格且不换行;左大括号后换行
if (flag == 1) {
System.out.println("world");
// 右大括号前换行,右大括号后有 else,不用换行
} else {
System.out.println("ok");
// 在右大括号后直接结束,则必须换行
}
}
-
注释的双斜线与注释内容之间有且仅有一个空格
// 注释
-
单行字符不能太长,超出换行并相对首行缩进4个空格,
.
参与换行,方法的参数则是,
后换行sb.append("zi").append("xin" .append("huang")... .append("huang1) .append("huang2)
-
IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式,不要使用 Windows 格式
OOP规约
-
避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可
-
所有的覆写方法,必须加@Override 注解。
-
接口过时必须加@Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么
-
任何货币金额,均以最小货币单位且整型类型来进行
-
关于基本数据类型与包装数据类型的使用标准如下
- 所有的 POJO 类属性必须使用包装数据类型。
- RPC 方法的返回值和参数必须使用包装数据类型
- 【推荐】所有的局部变量使用基本数据类
-
构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中。
-
POJO 类必须写 toString 方法
-
禁止在 POJO 类中,同时存在对应属性 xxx 的 isXxx()和 getXxx()方
-
在getter/setter 方法中,不要增加业务逻辑,增加排查问题的难度。
-
类成员与方法访问控制从严: 书中第25点 太长不弄上来
日期时间
-
不允许在程序任何地方中使用:1)java.sql.Date 2)java.sql.Time 3)ava.sql.Timestamp
Date真的是就日期,不包括时分秒
Time同理
TimeStamp 在构造方法 super((time/1000)*1000),fastTime 和 nanos 分开存储秒和纳秒信息。
-
获取当前毫秒数:System.currentTimeMillis(); 而不是 new Date().getTime()。
-
别忘了闰月的存在
集合处理
-
只要重写
equals
,就必须重写hashCode
。 -
如果自定义对象作为 Map 的键,那么必须覆写
hashCode
和equals
-
Set 存储的对象必须重写
hashCode
和equals
-
判断所有集合内部的元素是否为空,使用
isEmpty()
方法 -
不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁
List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (删除元素的条件) { iterator.remove(); } }
-
集合初始化时,指定集合初始值大,不确定就用16
-
高度注意 Map 类集合 K/V 能不能存储 null 值的情况
集合类 Key Value Super 说明 Hashtable 不允许为null 不 Dictionary 线程安全 ConcurrentHashMap 不 不 AbstractMap 锁分段技术 TreeMap 不 允许 AbstractMap 线程不安全 HashMap 允许 允许 AbstractMap 线程不安全 -
利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的contains()进行遍历去重或者判断包含操作
控制语句
-
在一个 switch 块内,都必须包含一个 default,语句并且放在最后,即使它什么代码也没有
-
在一个 switch 块内,每个 case 要么通过 continue/break/return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止
-
当 switch 括号内的变量类型为 String 并且此变量为外部参数时,必须先进行 null判断
-
在 if/else/for/while/do 语句中必须使用大括号,即使只有一行
-
在高并发场景中,避免使用”等于”判断作为中断或退出的条件,怕万一出现小于0的情况
-
判断条件别写太复杂
-
接口入参保护,这种场景常见的是用作批量操作的
注释规约
-
类、类属性、类方法的注释必须使用 Javadoc 规范
-
所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
-
所有的类都必须添加创建者和创建日期。idea模板的@author为
${USER}
/**
*@author yuan
*@date 2020/7/14
*/
-
方法内的注释单行用
// ...
多行用/*...*/
-
枚举类型字段都要有注释
-
代码改了注释别忘记改
-
注释代码需要谨慎,要有说明。没用就删
-
特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记
- 待办事宜 TODO: 标记人,标记时间,[预计处理时间]...
- 错误,不能工作 FIXME: 标记人,标记时间,[预计处理时间]...
并发处理
//TODO yuan 2020/7/14 详细学习并发
P20-P23
没细学,先不看
异常日志
p30
阿里的错误码有5位 好复杂,先不看
单元测试
p36
安全规约
p38