备注:笔记参考《阿里巴巴Java开发手册终极版v1.3.0》
下载链接: https://pan.baidu.com/s/1k4ujejAkRaUjhUP1IK_Cvw 提取码: hew3
一、编程规范
1、常量命名全部用大写,单词间用下划线隔开
正例:MAX_FLOW_NUM
反例:MAX_NUM
2、抽象类命名以Abstract或Base开头;异常类命名以Exception结尾
正例:AbstractBaseAction/BaseController
3、POJO类布尔类型变量,都不要加is,否则部分框架解析会引起序列化错误
反例:isDelete
备注:需要注意
4、杜绝完全不规范的缩写,避免产生歧义
反例:AbstractClass缩写为AbsClass
反例:int a,a没有意义,不可取
5、【推荐】如果模块、接口、类、方法使用了设计模式,在命名时体现出具体模式
说明:利于阅读者理解架构设计理念
正例:public class OrderFactory
6、【推荐】接口类中的方法和属性,不要加任何修饰符号(public也不要加),保持代码的简介性。尽量不要在接口里面定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量。
7、【推荐】枚举类名建议加上Enum后缀,枚举类名需要全部大写,单词间用下划线隔开
8、【参考】各层命名规约:
A)Service/DAO 层命名规约
1)获取单个对象的方法用get做前缀
2)获取多个对象的方法用list做后缀
反例:dispatchOrderService.find();//查询所有的调度记录
3)获取统计值的方法用count做前缀
4)插入的方法用save/insert 做前缀
5)删除的方法用remove/delete 做前缀
6)修改的方法用update 做前缀
二、代码格式
1、任何二目、三目运算符的左右两边,都需要加一个空格
2、采用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");
// 在右大括号后直接结束,则必须换行
}
}
3、注释的双斜线和注释内容之间,有且只有一个空格
正例://获取日期,姓名
4、单行字符数限制不超过120个,超出需要换行,换行时遵循如下原则:
第二行相对第一行缩进4个空格,从第三行开始,不再继续缩进
正例:
@Query(" SELECT o FROM RecordStatus o "
+ " WHERE (o.relatedName like :relatedName) "
+ " AND (o.id = :id) "
+ " ORDER BY o.relatedName,o.relatedType,o.orderNum")
5、方法参数在定义和传入时,多个参数逗号后必须加空格
正例:
super.update(operateType, params, id, newObjJson);
三、OOP规范
1、避免通过一个类的对象访问类的静态变量或静态方法
2、可变参数必须放在参数列表的最后(提倡进来不使用可变参数编程)
正例:
public User getUsers(String type, Integer... ids) {...}
备注:【可变参数】,三个点,解决参数个数不确定的问题
3、equlas方法容易抛空指针,应使用常量或确定值的对象放在左边,再调用equlas方法
String a = "hello";
String b = null;
正例:a.equlas(b); //结果是false
反例:b.equlas(a); //结果是java.lang.NullPointerException
解释:null不是String对象,null调用方法系统出现空指针异常,所以我们把明确的一定有值的那个变量放在前面。
4、基本数据类型和包装数据类型的使用标准:
1)所有的POJO类数据必须使用包装数据类型
2)【推荐】所有的局部变量使用基本数据类型
5、POJO必须重写toString方法
说明:如果没重写toString方法,返回的是一串看不懂的数字(Java对象的内存地址)。重写toString后,返回的是对象和值。
原始:
这是没有tostring重写实体类的时候!
调用实体类返回的是:demoTest_zt.toStringTest@15db9742
重写后:
这是有tostring重写实体类的时候!
调用实体类返回的是:toStringTest [name=zout, sex=man, No=1]
详情可参考:
https://blog.csdn.net/si444555666777/article/details/81531601
6、当一个类有多个构造方法,应该按顺序放置在一起
7、类内方法的定义顺序是:公有方法或保护方法 > 私有方法 > getter/setter 方法
说明:公有方法是类的调用者最关心的,应该首屏展示。私有方法外部一般不需要关心。
8、字符串拼接,首选StringBuilder的append方法
备注:
1)加号 “+” 拼接 更适合我们的阅读习惯
2)StringBuffer append() 方法,适合大批量数据处理
参考:
字符串拼接5种方法比较:https://www.cnblogs.com/twzheng/p/5923642.html
String,StringBuilder,StringBuffer区别:
String:少量字符串操作
StringBuilder:单线程下大量操作
StringBuffer: 多线程下大量操作
https://www.cnblogs.com/su-feng/p/6659064.html
9、类成员与方法访问控制从严
1)如果不允许外部直接通过new来创建对象,那么构造方法必须是private
2)工具类不允许有public或default构造方法
备注:工具类是一系列静态成员或方法的集合,意味着它不可以被实例化
3)类非static成员变量,并且与子类共享,必须是protected
4)类非static成员变量,并且仅在本类使用,必须是private
5)若static成员变量,必须考虑是否为final
1、关于hashCode和equals的处理
1)只要重写equals,就必须重写hashCode
参考:https://blog.csdn.net/freelander_j/article/details/52211010
2、不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。
正例:
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (删除元素的条件) {
iterator.remove();
}
}
反例:
List list = new ArrayList();
list.add("1");
list.add("2");
for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}
3、集合初始化时,指定集合初始值大小
备注:由于 没有设置容量 初始大小,随着元素不断增加容 量 7次被迫扩大, resize需要重建 hash表,严重影响性能。
注意:指定初始值大小,不影响list.size()的数值
疑问:自己测试了200万条数据,性能进差别50%,所以对此有疑问。
集合 |
Key |
Value |
线程安全 |
TreeMap |
不允许为null |
允许为null |
非线程安全 |
HashMap |
允许为null |
允许为null |
非线程安全 |
LindedHashMap |
允许为null |
允许为null |
非线程安全 |
HashTable |
不允许为null |
不允许为null |
线程安全(效率低) |
1、在一个switch块内,每个case要么通过break/return终止,要么注释说明程序将继续执行到哪一个case位置;
在一个switch块内,必须包含一个default语句并且放在最后,及时什么代码也没有。
/*
语法:
switch(表达式){
case 值1:
表达式的值和 值1匹配上了,需要执行的代码;
break;
case 值2:
表达式的值和 值2匹配上了,需要执行的代码;
break;
case 值3:
表达式的值和 值3匹配上了,需要执行的代码;
break;
default:
如果表达式的值和以上的case后面的值都没有匹配上,那么就执行这里的代码。
break;
}
* */
* //不写break会穿透到下一个break
2、表达异常的分支时,少用if-else方式
超过3层的 if-else 的逻辑判断代码可以使用卫语句,这种方式可以改成:
public void today() {
if (isBusy()) {
System.out.println("change time.");
return;
}
if (isFree()) {
System.out.println("go to travel.");
return;
}
System.out.println("good job!");
return;
}
备注:
【卫语句】把复杂的条件表达式拆分成多个条件表达式,比如一个很复杂的表达式,嵌套了好几层的if - then-else语句,转换为多个if语句,实现它的逻辑,这多条的if语句就是卫语句. 使用卫语句减少层级嵌套。
1、类、类属性、类方法的注释必须使用javadoc规范,使用/**内容*/格式,不得使用//xx方式
2、所有的抽象方法,必须使用javadoc注释,除了返回值、参数、异常说明外
3、所有的类都必须添加创建者和创建日期
4、方法内部单行注释,使用//注释
5、所以枚举类型字段都必须有注释,说明每个数据项的用途
6、代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑