Java开发手册

开发手册

名词解释

POJO(Plain Ordinary Java Object):专指setter / getter / toString的简单类,包括:DO / DTO / BO / VOjava

GAV(GroupId ArtifactctId Version):Maven坐标,用来惟一标识jar包git

OOP(Object Oriented Programming):泛指类、对象的基本编程处理方式github

ORM(Object Relation Mapper):对象关系映射、对象领域模型与底层数据之间的转换数据库

NPE(java.lang.NullPointerException):空指针异常编程

SOA(Service-Oriented Architecture):面向服务架构,根据需求经过网络对松散耦合的粗粒度应用软件进行分布式部署、组合使用设计模式

一方库:子项目模块依赖的库数组

二方库:Maven依赖的库网络

三方库:公司以外开源的库架构

IDE检测插件:github.com/alibaba/p3c并发

命名风格

  1. 命名不能如下划线或美圆符号开始,也不能如下划线或美圆符号结束。 反例:_name $name name_ name$
  2. 禁止拼音与英文混合方式,更不容许使用中文。通用名称,但是同英文:alibaba\taobao\youku\hangzhou
  3. 类名使用UpperCamelCase(首字母大写)风格,但DO、BO、DTO、VO、AO、PO等情形例外
  4. 方法名、参数名、成员变量、局部变量统一使用lowerCamelCase风格,必须遵照驼峰。例如:localValue/getHttpMessage()
  5. 常量命名所有大写,单词下划线分开,力求语义表达完整
  6. 抽象类命名使用Abstract或Base开头。异常类命名使用Exception结尾。测试类命名以它要测试的类名开始,Test结尾。
  7. 类型与中括号之间无空格相连定义数组。例如:int[] arrayDemo;
  8. POJO类中布尔类型的变量都不要加is前缀。不然部分框架解析会引发序列化错误
  9. 包名统一使用小写,点分隔符之间仅有一个天然语义的英文单词。包名统一使用单数形式,但类名若是有复数含义,则类名可使用复数形式。例如:com.alibaba.ai.util。类名MessageUtils
  10. 避免在子父类的成员变量之间或不一样代码块的局部变量之间采用彻底相同的命名方式,使其下降可读性
  11. 杜绝彻底不规范的缩写,避免词义不达标:例如:AbstractClass 缩写 AbsClass
  12. 任何自定义编程元素在命名时,使用尽可能完整的单词组合来表达其意。例如:对某个对象引用的volatile字段进行原子,AtomicReferenceFiledUpdater
  13. 常量与变量命名时,表达类型的名词放在词尾,以提高辨识度。例如:startTime\workQueue\nameList
  14. 若是模块、接口、类、方法使用设计模式,应该在命名时体现出具体模式。例如:LoginProxy、OrderFactory、ResourceObserver
  15. 接口类中的方法和属性不要加任何修饰符号(public 也不要加)保持代码的简洁性,并加上有效的Javadoc注释。尽可能不要在接口里定义变量,若是必定要定义变量,必须时与接口方法相关的,而且是整个应用的基础常量。
  16. 接口和实现类的命名有两套规则:
    1. 对于Service和DAO类,基于SOA的理念暴露出来的服务必定是接口,内部的实现类用Impl后缀与接口区别。例如:CacheServiceImpl 实现 CacheService接口
    2. 若是是形容能力的接口名称,取对应的形容词为接口名(一般是-able的形式)。例如:AbstractTranslator 实现 Translatable
  17. 枚举类名建议带上Enum后缀,成员名称须要全大写,单词下划线分割。例如:ProcessStatusEnum、SUCCESS
  18. 各层命名规约:
    1. Service/DAO层方法命名规约以下。
    • 获取单个对象的方法用get做为前缀
    • 获取多个对象的方法用list做为前缀,复数结尾,如listObjects。
    • 获取统计值的方法用count做为前缀
    • 插入的方法用save / insert做为前缀
    • 删除的方法用remove / delete 做为前缀
    • 修改的方法用update做为前缀
    1. 领域模型命名规约以下
    • 数据对象:xxxDO,xxx为数据表名
    • 数据传输对象:xxxDTO,xxx为业务领域相关名称
    • 展现对象:xxxVO, xxx通常为网页名称
    • POJO是统称,禁止命名

常量定义

  1. 不容许任何魔法值(未经预先定义的常量)直接出如今代码中
  2. long或者Long初始化赋值时,数值后使用大写的L,不能是小写。
  3. 不要使用一个常量类维护全部常量,要按照常量功能进行归类,分开维护
  4. 常量的复用层次有5层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量
    1. 跨应用共享:放置在二方库中,一般时client.jar中的constant目录下
    2. 应用内共享:放置在一方库中,一般实在子模块中的constant目录下
    3. 子工程内共享:当前子工程的constant目录下
    4. 包内共享:当前包下单独的constant目录下
    5. 类内共享:provate static final
  5. 若是变量值仅在一个范围内变化,则用enum类型来定义。例以下面代码

代码格式

  1. 大括号的使用约定,若是大括号内为空,则简洁地写成{}便可,大括号中间无须换行和空格。若是是非空代码块,则
    1. 左大括号前不换行
    2. 左大括号后换行
    3. 右大括号前换行
    4. 右大括号后还有else等代码不换行。终止的话必须换行
  2. 左小括号和字符间不出现空格,右小括号和字符间也不出现空格。左大括号前须要加空格
  3. if / for / while / switch / do 等保留关键字与括号之间必须加空格
  4. 任何二目、三目运算符左右两边都要加空格
  5. 采用4个空格缩进,禁止使用Tab控制符
  6. 注释的双斜线与注释内容之间有且仅有一个空格
  7. 进行类型强制转换时,右括号与强制转换值之间不须要任何空格隔开
  8. 单行字符数不超过120个,超出则须要换行,换行时遵循以下原则
    1. 第二行相对第一行缩进4个空格,第三行开始再也不持续缩进
    2. 运算符与下文一块儿换行
    3. 方法调用的点符号与下文一块儿换行
    4. 方法调用中的多个参数须要换行时,在逗号后进行
    5. 括号前不要换行
  9. 方法参数在定义和传入时,多个参数逗号后边必须加空格
  10. IDE的text file encoding设置为UTF-8,IDE中文件的换行符使用UNIX格式,不要使用Windows格式
  11. 没有必要增长若干空格来使变量的赋值等号与上一行对应位置的等号对齐
  12. 单个方法的总行数不超过80行
  13. 不一样逻辑、不一样语义、不一样业务的代码之间插入一个空行来分隔开,以提高可读性

OOP规约

  1. 避免经过一个类的对象引用方法此类的静态变量或静态方法。直接用类名来访问便可
  2. 全部的覆写方法,必须加@Override注解
  3. 相同参数类型,相同业务含义,才可使用Java的可变参数,避免使用Object
  4. 对外部正在调用或二方库依赖的接口,不容许修改方法签名,以免对接口调用方产生影响。若接口过期,必须加@Deprecated注解,并告知新接口或服务是什么
  5. 不能使用过期的类或方法
  6. Object的equals方法容易抛空指针异常,应使用常量或肯定有值的对象来调用equals
  7. 全部整型包装类对象之间值的比较,所有使用equals方法
  8. 浮点数之间的等值判断,基本数据类型不能用 == 进行比较,包括数据类型不能用equals方法进行判断。须要指定一个偏差范围,两个浮点数的差值在此范围以内则认为是相等的。
    1. 例如:float diff = 1e-6f;   Math.abs(a-b) < diff
    2. BigDecimal a,BigDecimal b; a.equalsb
  9. 定义数据对象DO类时,属性类型要与数据库字段类型相匹配。例如:数据库字段bigint类型必须与类属性Long类型相对应
  10. 禁止使用构造方法BigDecimal(double)的方式把 double 值转换为BigDecimal对象。会存在损失精度的风险。推荐:入参为String的构造、或BigDecimal.valueOf
  11. 基本数据类型与包装数据类型的使用标准以下
    1. 全部的POJO类属性必须使用包装数据类型。数据库查询结果可能为null,由于自动拆箱,基本数据类型有NPE风险
    2. RPC方法的返回值和参数必须使用包装数据类型
    3. 全部的局部变量使用基本数据类型。
  12. 定义DO/DTO/VO等POJO类时,不要设定任何属性默认值
  13. 序列化类新增属性时,请不要修改serialVersionUID字段,以免反序列化失败;若是不兼容升级,避免反序列化混乱,须要修改
  14. 构造方法禁止加入任何业务逻辑,若是有初始化逻辑,放在init方法中
  15. POJO类必须写toString方法。若是继承另外一个POJO类,注意添加super.toString()。解释:当方法抛出异常时,能够直接调用POJO的toString方法打印其属性值,便于排查
  16. 禁止在POJO类中,同时存在对应属性xxx的isxxx() 和 getXXX() 方法。框架在调用属性的提取方法时,并不能肯定哪一个方法优先调用到
  17. 当使用索引访问String的split方法获得的数组时,须要在最后一个分隔符后作有无内容的检查。不然会抛出IndexOutOfBoundsException的风险
  18. 当一个类有多个构造方法,或多个同名方式时,应该按照顺序放置在一块儿
  19. 类内方法定义顺序:公共方法或保护方法 > 私有方法 > getter / setter
  20. 在setter方法中,参数名称与类成员变量名称一致,this.成员名 = 参数名。不要增长业务逻辑,不然会增长排查问题的难度
  21. 循环体内,字符串的链接方式使用StringBuilder的append方法进行扩展。不要使用字符串
  22. final能够声明类、成员变量、本地方法及本地变量。推荐使用状况以下
    1. 不容许被继承的类
    2. 不容许修改引用的域对象
    3. 不容许被重写的方法
    4. 不容许运行过程当中从新赋值的局部变量
    5. 避免上下文重复使用一个变量,使用final描述能够强制从新定义一个变量,方便更好地进行重构
  23. 慎用Object的clone方法来拷贝对象。由于是浅拷贝
  24. 类成员与方法访问控制从严
    1. 若是不容许外部直接经过new来建立对象,那么构造必须限制private
    2. 工具类不容许有Public或default构造方法
    3. 非静态成员变量而且与子类共享,必须限制为protected
    4. 非静态成员变量而且仅在本类使用,必须限制为private
    5. 静态成员变量若是仅在本类使用,必须限制为private
    6. 如果static成员变量,必须考虑是否为final
    7. 类成员方法只供类内部调用,必须限制为private
    8. 类成员方法只对继承类公开,限制为protected

集合处理

  1.  关于hashCode和equals的处理,遵循以下规则:
    1. 只要重写equals,就必须重写hashCode
    2. 由于Set存储的是不重复的对象,依据hashCode和euqals进行判断,因此Set存储的对象必须重写这两种方法
    3. 若是自定义对象做为Map的键,那么必须重写hashCode和equals
  2. 使用Map的方法keySet()/values()/entrySet(),返回集合对象时,不能够对其添加元素,不然回抛出异常
  3. Collections类返回的对象,如emptyList()/singletonList()等都是immutable list,不能够对其添加或者删除元素
  4. ArrayList的subList结果不可强转成ArrayList,不然回抛出异常。解释:subList返回的时ArrayList的内部类,并非ArrayList
  5. 在subList场景中,高度注意对原集合元素的增长或删除,均会致使子列表的遍历、增长、删除均产生异常
  6. 使用集合转数组的方式,必须使用集合的toArray(T[] array),传入的类型是彻底同样的数组,大小就是list.size()。
  7. 在使用Collection接口任何实现类的addAll()方法时,都要对输入的集合参数进行NPE判断
  8. 使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add / remove / clear方法会抛出异常。
    1. asList的返回对象是一个Arrays内部类,并无实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据还是数组
  9. 泛型通配符<? extends T>用来接收返回的数据,此写法的泛型集合不能使用add方法,而<? super T> 不能使用get方法,由于其做为接口调用赋值很容易出错
    1. PECS(Producer Extends Consumer Super)原则:第一,频繁往外读取内容的,适用于<? extends T>;第二,常常往里插入的,适用于<? super T>
  10. 无泛型限制定义的集合赋值给泛型限制的集合时,当使用集合元素时,须要进行性instanceof判断,避免抛出ClassCastException异常
  11. 不要再foreach循环里进行元素的remove / add操做。remove元素请使用Iterator方式,若是并发操做,须要对Iterator对象加锁。
  12. Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()){
        String item = iterator.next();
        if (删除元素的条件){
            iterator.remove();
        }
    }        

 

 

 

 

 

 

 

相关文章
相关标签/搜索