01_编程规约——OOP规约
1.【强制】避免通过⼀个类的对象引⽤访问此类的静态变量或静态⽅法,避免增加编译器解析成本,直接⽤“类名.变量名”访问即可。
2.【强制】所有的覆盖⽅法,必须加@Override注解
说明:加@Override可以准确判断是否覆盖成功,另外如果在抽象类中对⽅法签名进⾏修改,对应的实现类会马上报编译错误。
3.【强制】相同的参数类型,相同业务含义,才可以使⽤Java的可变参数( ids),避免使⽤Object。(注意:尽量不要⽤可变参数编程)
说明:可变参数必须放在参数列表的最后。
⾮得使⽤的话,例⼦:public User getUsers(String type, ids){...}
4.【强制】外部正在调⽤或者⼆⽅库依赖的接⼝,不允许修改⽅法签名,避免对接⼝调⽤产⽣影响。接⼝过时必须加@Deprecated注解,并清晰地说明采⽤的新接⼝或者新服务是什么。
5.【强制】不能使⽤过时的类和⽅法。
6.【强制】Object的equals⽅法容易抛空指针异常,应该使⽤常量或者确定有值的对象来调⽤equals⽅法。
正例:"test".equals(object)
反例:object.equals("test")
说明:推荐使⽤java.util.Objects#equals
7.【强制】所有的相同类型的包装类对象之间的值⽐较,全部使⽤equals⽅法⽐较。
说明:对于Integer var= ? 在-128⾄127范围内的赋值,Integer对象是在IntegerCache.cache产⽣,产⽣,会复⽤已有对象,在这个区间的值可以直接使⽤==进⾏判断,但是这个区间之外的数据,都会在堆上产⽣,并不会复⽤已有对象,是⼀个⼤坑,推荐使⽤equals⽅法进⾏判断。
8.关于数据基本类型与包装数据类型的使⽤标准如下:
  8.1【强制】所有的POJO类属性必须使⽤包装数据类型。
  8.2【强制】RPC⽅法的返回值和参数必须使⽤包装数据类型。
  8.3【推荐】所有的局部变量使⽤基本数据类型。
说明:POJO类属性没有初值是提醒使⽤者在需要使⽤时,必须⾃⼰显式地进⾏赋值,任何NPE问题,或者⼊库检查,都由使⽤者来保证。正例:数据库的查询结果可能是null,因为⾃动拆箱,⽤基本数据类型接收会有NPE风险。
反例:⽐如成交总额的涨跌情况,即为±x%,x为基本数据类型,在调⽤RPC服务,调⽤不成功时,返回的是默认值,页⾯显⽰为±0%,这是不合理的,应该显⽰成中划线-,所以包装数据类型的null值,能够表⽰额外的信息,如远程调⽤失败,异常退出。
9.【强制】定义DO/DTO/VO等POJO类时,不要设定任何属性为默认值。
反例:POJO类的gmtCreate默认值为new Date(),但是这个属性在数据提取时并没有置⼊具体值,在更新其他字段时⼜附带更新了此字段,导致创建时间被修改成当前时间。
10.【强制】序列化类新增属性时,不要修改serialVersionUID字段,避免反序列化失败:如果完全不兼容升级,避免反序列化混乱,那么修改serialVersionUID值。
说明:注意serialVersionUID不⼀致会抛出序列化运⾏时异常。
11.【强制】构造⽅法⾥⾯禁⽌加⼊任何业务逻辑,如果有初始化逻辑,请放在init⽅法中。
12.【推荐】POJO类必须写toString()⽅法。
如果继承了另⼀个POJO类时,注意在前⾯加⼀下String()。
说明:在⽅法执⾏抛出异常时,可以直接调⽤POJO的toString()⽅法打印其属性值,便于排查问题。
13.【推荐】使⽤索引访问String的split⽅法得到的数组,需要做最后⼀个分隔符后有⽆内容的检查,否则会有抛出IndexOutOfBoundsException数组越界的风险。
说明:String str = "a,b,c,,";
  String[] ary = str.split(",");
  System.out.println(ary.length); //预期是⼤于3,但是结果是3。
14.【推荐】当⼀个类由多个构造⽅法,或者多个同名⽅法,这些⽅法应该按顺序放在⼀块,便于阅读。(此规则优先于第15条规则)
15.【推荐】类内⽅法的定义的放置顺序依次是:public/protected⽅法>private⽅法>getter/setter⽅法。
说明:public⽅法是类的调⽤者和维护者最关⼼的⽅法,⾸屏展⽰最好。
protected⽅法虽然只是⼦类关⼼,但是也有可能是“模板设计模式”下的核⼼⽅法。
private⽅法外部⼀般不需要特别关⼼,是⼀个⿊盒实现。
16.【推荐】setter⽅法中,参数名称与类成员变量名称保持⼀致,this.成员变量=参数名。
在getter/setter⽅法中,尽量不要增加业务逻辑,增加排查问题的难度。
17.【推荐】循环体内,字符串的连接⽅式,使⽤StringBuilder的append⽅法进⾏扩展。
说明:反编译出的字节码⽂件显⽰使⽤String时,每次循环都会new出⼀个新的StringBuilder对象,然后进⾏append操作,最后toString⽅法会返回String对象,造成内存资源的浪费。
反例:
String str = "start";
for(int i=0;i<100;i++){
  str = str + "hello";equals()方法
}
18.【推荐】final可以声明类,成员变量,⽅法,以及本地变量,下列情况使⽤final关键字:
  18.1 不允被继承的类,如String类。
  18.2 不允许修改引⽤的域对象,如POJO类的域对象。
  18.3 不允许被重写的⽅法,如POJO类的setter⽅法。
  18.4 不允许运⾏过程汇总重新赋值的局部变量。
  18.5 避免上下⽂重复使⽤⼀个⼀个变量,使⽤final描述可以强制重新定义⼀个变量,⽅便更好地进⾏重构。
19.【推荐】谨慎使⽤Object的clone⽅法来拷贝对象。
说明:对象的clone⽅法默认是浅拷贝,若想实现深拷贝需要重写clone⽅法数显属性对象的拷贝。
20.【推荐】类成员变量与⽅法访问控制从严:
  20.1 如果不允许外部直接通过new来创建对象,那么构造⽅法必须是private。
  20.2 ⼯具类不允许有public或default构造⽅法(⼯具类⼀般所有⽅法都是静态⽅法)。
  20.3 类⾮static 成员变量并且与⼦类共享,必须是protected。
  20.4 类⾮static成员变量并且仅在本类使⽤,必须是private
  20.5 类static 成员变量如果尽在本类使⽤,必须是private
  20.6 若是static成员变量,必须考虑是否为final
  20.7 类成员⽅法只供类内部使⽤,必须是private
  20.8 类成员⽅法只对继承公开,那么限制为protected

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。