阿里巴巴Java开发手册阅读笔记

备注:笔记参考《阿里巴巴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<String> iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

    if (删除元素的条件) {

        iterator.remove();
    }
}

反例:

List<String> list = new ArrayList<String>();

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%,所以对此有疑问。

  1. Map类集合K/V 能不能存储null值的情况,如下表格:

集合

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、代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑

猜你喜欢

转载自blog.csdn.net/qq_37436998/article/details/83416705