命名风格

1、代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结尾。

反例:_name / $name / name_ / name$

2、类名使用UpperCamelCase风格,但以下情形例外:DO/BO/DTO/VO/AO/PO等

正例:MarcoPolo/UserDO/XmlService

反例:macroPolo/userDo/XMLService

3、常量命名全部用大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌弃名字长。

正例:MAX_STCK_COUNT

4、抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的类的名称开头,以Test结尾。

5、POJO类中布尔类型的变量,都不要加is,否则部分框架解析会英气序列化错误。

反例:定义为基本数据类型Boolean isDeleted;的属性,它的方法也是isDeleted();框架在反向解析的时候,“以为”对应的属性名称是deleted,导致属性获取不到,进而抛出异常。

6、包名统一使用小写,点分隔之间有且仅有亿个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。

正例:应用工具类包名为:com.alibaba.open.util 、类名为MessageUtils(此规则参考spring)

7、如果模块、接口、类、方法使用了设计模式,在命名时体现出具体模式。说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。

正例:pubic class OrderFactory

Public class LoginProxy

8、杜绝完全不规范的缩写,避免望文不知义;

反例:AbstractClass 缩写命名成AbsClass;condition缩写命名成condi,此类随意缩写严重降低了代码的可阅读性。

9、接口类中的方法和属性不要加任何修饰符(public也不要加),保持代码的简洁性,并加上有效的javadoc注释,尽量不要在接口定义变量,如果一定要定义变量,肯定是与接口方法有关,并且是整个应用的基础变量。

正例:接口方法签名:void f();

接口基础常量表示:String COMPANY="alibaba";

说明:JDK中接口允许有默认实现,那么这个default方法,是对所有实现类都有价值的默认实现。

10、枚举类名建议带上Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开。

说明:枚举其实就是特殊的常量类,且构造方法默认强制私有。

正例:枚举名字为ProcessStatusEnum的成员名称:SUCCESS/ UNKNOWN_REASON。

11、各层命名规约(做参考)

A)Service/DAO层方法命名规约

1)获取打个对象的方法用get前缀

2)获取多个对象的方法用list做前缀

3)获取统计值的方法用count前缀

4)插入的方法用save/insert前缀

5)删除的方法用remove/delete做前缀

6)修改的方法用update做前缀

B)领域模型命名规约

1)数据对象:xxxDO,xxx为数据表名

2)数据传输对象:XXXDTO,xxx为业务领域相关的名称

3)展示对象:xxxVO,xxx一般为网页名称

4)POJO是DO/DTO/BO/VO的统称,禁止命名为xxxPOJO

二 常量定义

1、不允许任何魔法值(即未经定义的常量)直接出现在代码中。

反例:String key="Id#taobao_"+tradeId;

cache.put(key,value);

2、long或者Long初始赋值时,使用大写L,不能小写的l,小写容易与数字1混淆,造成误解。

说明:Long a=2l;写的是数字21还是Long型2?

3、不要使用一个常量类维护所有常量,按常量功能进行归类,分开维护。

说明:大而全的常量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。

正例:缓存相关常量放在类CacheConts下;系统配置相关常量放在类ConfigConsts下。

OOP规约

1、避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。

2、所有的覆写方法,必须加@Override注解

说明:getObject()与get0bject()的问题。一个是字母O,一个是数字0,加@Override可以准确判断是否覆盖成功。另外,如果在抽象类中方法签名进行修改,其实现类马上编译报错。

3、相同参数类型,相同业务含义,才可以使用java的可变参数,避免使用Object。

说明:可变参数必须放置在桉树列表的最后。(提倡大家尽量不用可变参数编程)

4、Object的equeal方法很容易抛空指针异常,应使用常量或确定有值的对象来调用。

正例:“Test”.equal(test);

反例:test.equal("Test");

5、所有的相同类型的包装类对象之间值的比较,全部使用equals方法比较。

说明:对于Integer i=? 在-128到127范围内的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这个坑比较大,建议用equals比较。

6、关于基本数据类型和包装数据类型的使用标准

1、所有的POJO类属性必须使用包装数据类型

2、RPC方法的返回值和参数必须使用包装数据类型

3、所有局部变量使用基本数据类型(参考)。

说明:POJO类属性没有初始值是提醒使用者在需要使用时,必须自己显示的进行赋值,任何NPE(空指针异常)问题,或者入库检查,都由使用者保证。

7、定义DO/DTO/VO等POJO类时,不要设定任何初始值。

8、构造方法里面禁止加入任何业务逻辑,如果有初始化的逻辑,请昂在init方法中。

9、POJO类必须写toString方法。

说明:在方法执行抛出异常时,可以直接调用toString()方法进行打印其属性,便于排查问题。

10、循环体内,字符串的拼接使用StringBuff的append方法进行扩展。

11、慎用Object的clone方法来拷贝对象。

说明:colne方法默认是浅拷贝,浅拷贝:引用类型的属性,修改复制后的对象,则原对象也会改变。如果想实现深拷贝要重写clone方法实现属性对象的拷贝。

12、严控域,类成员与方法访问控制从严;

集合处理

1、ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCasrException异常;

说明:subList返回的是ArrayList的内部类SubList,并不是ArrayList,而是ArrayList的一个视图,对于SubList子列表的所有操作最终都会反映到原列表上。

2、在subList场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均会产生异常。

3、使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size();

说明:使用toArray带参方法,入参分配的数组空间不够大时,toArra方法内部将重新分配内存空间,并返回新数组地址:如果数组元素大于实际所需,下表[list.size()]的数组元素将被置为null,其他数组元素保持原值,因此最好将方法入参数组大小定为与集合元素个数一致。直接使用toArray无参方法存在问题,此方法返回值只能Object[]类,若强转其他的类型数组将出现类转换异常。

4、使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出异常。

说明:asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。

5、不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。

6、集合初始化时,指定集合初始化大小。

说明:HashMap使用HashMap(int initialCapacity)初始化。initialCapacity=(需要存储的元素个数/负载因子)+1。注意:负载因子(loaderfactor)默认为0.75,如果暂时无法确定初始值大小,请设置为16(即默认值)。

反例:HashMap需要放置1024个元素,由于没有设置初始化大小,随着元素不断增加,容量7扩容,resize需要重建hash表,严重影响性能。

7、使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。

说明:keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的Value。而entrySet只是遍历一次就把key和Value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。

8、高度注意Map集合K/V能不能存储null值的情况,如下:

集合类

Key

Value

Super

说明

Hashtable

不允许为null

不允许为null

Dictionary

线程安全

ConcurrentHashMap

不允许为null

不允许为null

AbstractMap

锁分段技术(JDK8:CAS)

TreeMap

不允许为null

允许为null

AbstractMap

线程不安全

HashMap

允许为null

允许为null

AbstractMap

线程不安全

控制语句

1、表达异常的分支时,少用if-else方式。

说明:如果非得用if()…else if()…else…方式表达逻辑,避免后续代码维护困难,请勿超过3层。超过三层的的逻辑可以用卫语句、策略模式、状态模式等来实现。

2、除常用方法外,不要在条件判断中执行其他复杂的语句,将复杂的逻辑的判断结果赋值给一个有意义的布尔值变量

3、循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库链接,进行不必要的try-catch操作

4、下列情况,需要进行参数校验:

1)调用频次低的方法

2)执行时间开销很大的方法,此情形中,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,那就得不偿失。

3)需要极高稳定性和可用性的方法。

4)对外提供的开放接口,不管是RPC/API/HTTP接口

5)敏感权限入口

注释规约

1、类、类属性、类方法的注释必须使用Javadoc规范。

其他

1、不要在视图模板中加入任何复杂的逻辑

说明:根据MVC理论,视图的职责是展示,不要抢模型和控制器的活;

2、任何数据结构的构造或初始化,都应指定大小,避免数据结构无限次增长吃光内存。

阿里巴巴Java开发手册摘要(一)的更多相关文章

  1. 阿里巴巴Java开发手册摘要(二)

    MySql数据库 一建表规约 1.表达是与否概念的字段,必须使用is_xxx的命名方式,数据类型是unsigned tinyint(1:是,0否) 正例:表达逻辑删除的字段名is_deleted,1表 ...

  2. 2019.05.26 周日--《阿里巴巴 Java 开发手册》精华摘要

    一.写在开头 Java作为一个编程界最流行的语言之一,有着很强的生命力.代码的编写规范也是不容忽视的,今天,我就把自己阅读的国内的互联网巨头阿里巴巴的<阿里巴巴 Java 开发手册>一些精 ...

  3. 阿里巴巴Java开发手册———个人追加的见解和补充(一)

    先上干货,<阿里巴巴Java开发手册>的下载地址 https://yq.aliyun.com/articles/69327?spm=5176.100239.blogcont69327.15 ...

  4. 阿里巴巴Java开发手册评述

    2016年底的时候阿里巴巴公开了其在内部使用的Java编程规范.随后进行了几次版本修订,目前的版本为v1.0.2版.下载地址可以在其官方社区-云栖社区https://yq.aliyun.com/art ...

  5. 阿里巴巴Java开发手册快速学习

    Java作为一门名副其实的工业级语言,语法友好,学习简单,大规模的应用给代码质量的管控带来了困难,特别是团队开发中,开发过程中的规范会直接影响最终项目的稳定性. 善医者“未有形而除之”,提高工程健壮性 ...

  6. 《阿里巴巴Java开发手册(正式版》读记

    前几天,阿里巴巴发布了<阿里巴巴Java开发手册(正式版>,第一时间下载阅读了一番. 不同于一般大厂内部的代码规范,阿里巴巴的这本Java开发手册,可谓包罗万象,几乎日常Java开发中方方 ...

  7. 读阿里巴巴Java开发手册v1.2.0之工程结构有感【架构篇】

    首先,把昨天那俩条sql语句的优化原因给大家补充一下,第一条效率极低,第二条优化后的,sql语句截图如下: 经过几个高手的评论和个人的分析: 第一条sql语句查询很慢是因为它首先使用了in关键字查询, ...

  8. 读阿里巴巴Java开发手册v1.2.0之编程规约有感【架构篇】

     不为过去蹉跎,改变当下. 为什么开篇就送这么一句话给大家,我相信很多处于1-3年码龄的哥们儿们,在平时的编码历程中编码的个性可能是多彩的,每个人都有每个人特定的风格,但是我们现在这么随意写,以后这么 ...

  9. 读书笔记 之 《阿里巴巴Java开发手册》

    一.前言 这本书主要定义了一些代码的规范以及一些注意事项.我只根据我自己的不足,摘录了一些内容,方便以后查阅. 二.读书笔记 命名 1.代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符 ...

随机推荐

  1. The Ninth Week (Lucklyzpp)

    The Ninth Week  (Lucklyzpp) 1.简述DNS服务器原理,并搭建主-辅服务器. [10:36:39 root@lucklyzpp ~]#vim /etc/named.conf ...

  2. RabbitMQ (五):死信队列

    什么是TTL RabbitMQ的TTL全称为Time-To-Live,表示的是消息的有效期.消息如果在队列中一直没有被消费并且存在时间超过了TTL,消息就会变成了"死信" (Dea ...

  3. xpath的chrome插件安装,xpath基本语法

    xpath插件安装: 注意:提前安装xpath插件 (1)打开chrome浏览器 (2)点击右上角小圆点 (3)更多工具 (4)扩展程序 (5)拖拽xpath插件到扩展程序中 (6)如果crx文件失效 ...

  4. CodeBlocks调试器缺少(gdb.exe)文件

    错误如下: Building to ensure sources are up-to-date Selecting target:  Debug ERROR: You need to specify ...

  5. [luogu7476]苦涩

    维护线段树,在其每一个节点上维护一个set(可重),以及子树内所有set的最大值 考虑下传标记,如果将所有元素全部下传复杂度显然不正确,但注意到我们仅关心于其中的最大值,即仅需要将最大值下传即可 其有 ...

  6. [hdu6600]Just Skip The Problem

    1.直接令x=0,为了判断这一信息,对于所有含有多个1的yi,必然是无用的,答案至少为n且不能含有多位1的y2.令yi=2^(i-1),由此发现一定可以得到x每一位的答案,即答案最多为n.因此,发现方 ...

  7. Stream流的使用

    创建流 创建流的方式很多,从jdk8起,很多类中添加了一些方法来创建相应的流,比如:BufferedReader类的lines()方法:Pattern类的splitAsStream方法.但是开发中使用 ...

  8. ES2020新特性链操作符 '?.'和'??'

    ES2020新特性,js中的可选链操作符?. 概述 回想一下,我们是如何访问可能含有空值(null或undefined)属性的嵌套对象,比如访问web api 返回结果的user详情,可以使用嵌套的三 ...

  9. Codeforces 690A2 - Collective Mindsets (medium)

    Codeforces 题面传送门 & 洛谷题面传送门 一道脑筋急转弯的结论题. 首先我们考虑对于某个特定的金币数 \(m\),有哪些 \(n\) 满足条件.考虑最 naive 的情况,\(m= ...

  10. [R] cbind和filter函数的坑

    最近我用cbind函数整合数据后,再用filter过滤数据,碰到了一个大坑. 以两组独立样本t检验筛选差异蛋白为例进行说明吧. pro2 <- df2[1:6] Pvalue<-c(rep ...