目录
一、编程规约
(一) 命名规范
(二) 常量定义
(三) 代码格式
(四) OOP规约
(五) 日期时间
(六) 集合处理
(七) 并发处理
(八) 控制语句
(九) 注释规约
(十) 前后端规约
二、异常日志
(一) 错误码
(二) 异常处理
(三) 日志规约
三、单元测试
四、安全规约
五、MySQL数据库
(一) 建表规约
(二) 索引规约
(三) SQL语句
(四) ORM映射
六、工程结构
(一) 应用分层
(二) 二方库依赖
(三) 服务器
七、设计规约
一、编程规约
(一) 命名规范
1. 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。 反例:_name / __name / $name / name_ / name$ / name__ 。
2. 禁止使用拼音和英文混合。反例:DaZhePromotion [打折] / getPingfenByName() [评分] 。
3. 类名使用大驼峰式命名法;方法名、参数名、成员变量、局部变量都统一使用小驼峰式命名法。
4. 常量命名全部大写,单词间用下划线隔开;例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME 。
5. 类型与中括号紧挨相连来表示数组。 例:定义整形数组 int[] arrayDemo。
6. boolean类型变量,不要以is开头,避免部分序列化框架出错。反例:boolean isExists。
7. 杜绝完全不规范的缩写,避免望文不知义。 反例:AbstractClass“缩写”成AbsClass;condition“缩写”成 condi。
8. 对于Service和DAO类,一定是接口,实现需要以Impl的后缀结尾。区别于接口
如:CacheService CacheServiceImpl。
9. 枚举类名带上Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开。
10. 类接口中属性和方法不要加任何修饰符。
(二) 常量定义
1. 不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。 反例:String key = “id=” + id;
2. long和Long初始赋值时,必须使用大写,为了避免和数字1搞混。
例:Long a = 2L 反例:Long a = 2l
3. 不要使用一个常量类维护所有常量,尽可能根据功能进行拆分归类,分开维护。便于理解和维护。
(三) 代码格式
1. 如果是大括号内为空,则写成{}即可,大括号中间无需换行和空格;如果是非空代码块则:( 1) 左大括号前不换行,左大括号后换行。 (2) 右大括号前换行。
2. 左括号与后一个字符之间不出现空格,右括号与前一个字符之间不出现空格
例:if (flag == 0)。
3. if/for/while/switch/do 等保留字与括号之间都必须加空格。
4. 何二目、三目运算符的左右两边都需要加一个空格。
5. 注释的双斜线与注释内容之间有且仅有一个空格。
6. 方法参数在定义和传入时,多个参数逗号后必须加空格。 例:method(“a”, “b”, “c”);
(四) OOP规约
1. 直接使用类名来访问一个类的静态变量或静态方法。
2. 所有的覆写方法,必须加@Override注解,可以准确判断是否覆盖成功。
3. 对外的接口,原则上避免修改,可以增加新接口,过时接口使用@Deprecated注解
4. Object的 equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。例:"test".equals(object);
5. 所有整型包装类对象之间值的比较,全部使用equals方法比较,使用==进行判断的话会有数值范围的限制。
6. 循环体内字符串拼接,使用StringBuilder的append方法。
7. 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init方法中。
8. 浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用equals 来判断。
(五) 日期时间
1. 日期格式化时,传入pattern 中表示年份统一使用小写的y。
2. 获取当前毫秒数:System.currentTimeMillis(); 而不是new Date().getTime()。
(六) 集合处理
1. 只要重写equals,就必须重写hashCode。
2. 判断所有集合内部的元素是否为空,使用isEmpty()方法,而不是size()==0的方式。
3. ArrayList的subList方法结果不可转成ArrayList。(subList返回的是ArrayList的内部类,并不是ArrayList,而且是ArrayList的一个视图,对SubList所有的操作都会反映到ArrayList原列表上。)
4. 使用集合转数组方法,必须使用集合的toArray(T[] array)。
5. 不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator 方式,如果并发操作,需要对Iterator对象加锁。
6. 使用工具类Arrays.asList()将数组转换成集合时,不能使用修改集合相关方法,如:add/remove/clear都将抛出UnsupportedOperationException异常。
(七) 并发处理
1. 获取单例对象需要保证线程安全,其中的方法也要保证线程安全。
2. 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程,避免过多创建线程、减少创建和销毁线程开销。
3. 线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,Executors返回的线程池对象的缺点是可能会创建大量线程或堆积大量请求,导致OOM。
4. 并发情况,多考虑锁的性能损耗。能不用锁就不用锁;能锁区块,就不要锁整个方法;能锁对象就别锁类。
5. 对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。
6. 如果访问冲突概率不高,推荐使用乐观锁。
7. HashMap 在容量不够进行resize时由于高并发可能出现死链,导致CPU飙升,在 开发过程中注意规避此风险。
8. ThreadLocal对象建议使用static修饰
(八) 控制语句
1. switch块内,每个case要么通过break/return终止,要么注释说明将执行到哪一个case为止;在一个switch必须包含default,就算是空的。
2. 当switch 括号内的变量类型为String并且此变量为外部参数时,必须先进行null 判断。
3. 在 if/else/for/while/do语句中必须使用大括号。
4. 在高并发场景中,避免使用”等于”判断作为中断或退出的条件。 反例:判断剩余奖品数量等于 0 时,终止发放奖品,但因为并发处理错误导致奖品数量瞬间变成了负数, 这样的话,活动无法终止。
(九) 注释规约
1. 类、类属性、类方法的注释必须使用Javadoc规范,使用/**内容*/格式,不得使用 // xxx方式。
2. 所有的抽象方法(包括接口中的方法),必须要用Javadoc注释
3. 所有的类都必须添加创建者和创建日期。
(十) 前后端规约
1. 前后端交互的API,需要明确协议、域名、路径、请求方法、请求内容、状态码、响应体。
2. 前后端数据列表相关的接口返回,如果为空,则返回空数组[]或空集合{}。
3. 服务端发生错误时,返回给前端的响应信息必须包含HTTP状态码,errorCode、 errorMessage、用户提示信息四个部分。
二、异常日志
(一) 错误码
1. 错误码不体现版本号和错误等级信息。
2. 错误码不能直接输出给用户作为提示信息使用。
(二) 异常处理
1. 不要捕获继承自RuntimeException的运行时异常,这类异常需要自行检查规避,如:IndexOutOfBoundsException / NullPointerException。
2. 异常捕获后不要用来做流程控制,条件控制。
3. 捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。
4. finally块必须对资源对象、流对象进行关闭,有异常也要做try-catch;不要在finally块中使用return。
(三) 日志规约
1. 不要执行使用日志实现类,而应该使用SLF4J的API接口,使用门面模式,容易做到所有类的日志处理方式统一。
2. 所有日志文件至少保存15天,因为有些异常具备以“周”为频次发生的特点。
3. 避免重复打印日志,浪费磁盘空间,务必在日志配置文件中设置 additivity=false。
4. 日志打印时禁止直接用JSON工具将对象转换成String。
三、单元测试
1. 好的单元测试必须遵守 AIR原则,即具有自动化、独立性、可重复执行的特点。
2. 单元测试是可以重复执行的,不能受到外界环境的影响。
3. 保持单元测试的独立性。为了保证单元测试稳定可靠且便于维护,单元测试用例之间 决不能互相调用,也不能依赖执行的先后次序。
四、安全规约
1. 隶属于用户个人的页面或者功能必须进行权限控制校验。
2. 用户敏感数据禁止直接展示,必须对展示数据进行脱敏。
3. 用户输入的 SQL参数严格使用参数绑定或者 METADATA字段值限定,防止 SQL注入, 禁止字符串拼接 SQL访问数据库。
4. 表单、AJAX提交必须执行 CSRF安全验证。
五、MySQL数据库
(一) 建表规约
1. 表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint (1表示是,0表示否)。
2. 表名字段名必须使用小写字符或数字;禁止出现数字开头,禁止两个下划线之间只有数字。例:aliyun_admin,rdc_config,level3_name。
3. 禁用保留字,如desc、range、match、delayed等。
4. 表名不使用复数名词。
5. 主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。 说明:pk_ 即primary key;uk_ 即 unique key;idx_ 即index的简称。
6. 小数类型为decimal,禁止使用float和double。
7. 如果存储的字符串长度几乎相等,使用 char定长字符串类型。
8. varchar为变长字符串,长度不要超过5000,如果存储长度超过该值,使用text,并独立表出来。
9. 表必备三字段:id, create_time, update_time。
(二) 索引规约
1. 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。
2. 超过三个表禁止 join。需要 join的字段,数据类型保持绝对一致;多表关联查询时, 保证被关联的字段需要有索引。
3. 在 varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据 实际文本区分度决定索引长度。
4. 严禁左模糊或者全模糊。
5. 利用覆盖索引来进行查询操作,避免回表。
(三) SQL语句
1. 不要使用count(列名)或count(常量)来替代count(*),count(*)是SQL92定义的标 准统计行数的语法,跟数据库无关,跟NULL和非 NULL无关。
2. 当某一列的值全是NULL时,count(col)的返回结果为0,但 sum(col)的返回结果为 NULL,因此使用sum()时需注意NPE问题。
3. in操作能避免则避免,若实在避免不了,需要仔细评估 in后边的集合元素数量,控 制在1000个之内。
(四) ORM映射
1. 在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。
2. POJO类的布尔属性不能加is,而数据库字段必须加is_,要求在resultMap中进行 字段与属性之间的映射。
3. sql.xml配置参数使用:#{},#param# 不要使用${} 此种方式容易出现 SQL注入。
4. 更新数据表记录时,必须同时更新记录对应的update_time字段值为当前时间。
六、工程结构
(一) 应用分层
1. 分层领域模型规约:
• DO(Data Object):此对象与数据库表结构一一对应,通过 DAO层向上传输数据源对象。
• DTO(Data Transfer Object):数据传输对象,Service 或Manager 向外传输的对象。
• BO(Business Object):业务对象,可以由Service层输出的封装业务逻辑的对象。
• Query:数据查询对象,各层接收上层的查询请求。注意超过2 个参数的查询封装,禁止使用 Map 类 来传输。
• VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
(二) 二方库依赖
1. 二方库版本号命名方式:主版本号.次版本号.修订号。
2 .二方库里可以定义枚举类型,参数可以使用枚举类型,但是接口返回值不允许使用枚 举类型或者包含枚举类型的 POJO对象。
3. 依赖于一个二方库群时,必须定义一个统一的版本变量,避免版本号不一致。
4. 禁止在子项目的 pom依赖中出现相同的 GroupId,相同的 ArtifactId,但是不同的 Version。
(三) 服务器
1. 高并发服务器建议调小 TCP协议的 time_wait超时时间。
2. 给JVM环境参数设置-XX:+HeapDumpOnOutOfMemoryError参数,让JVM碰到OOM 场景时输出dump 信息。
七、设计规约
1. 在需求分析阶段,如果与系统交互的User超过一类并且相关的User Case超过5个, 使用用例图来表达更加清晰的结构化需求。 文章来源:https://www.toymoban.com/news/detail-428635.html
2. 如果某个业务对象的状态超过3个,使用状态图来表达并且明确状态变化的各个触发条件。文章来源地址https://www.toymoban.com/news/detail-428635.html
到了这里,关于阿里开发手册规范(JAVA)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!