Java开发手册-2

本文详细规定了Java代码的格式规范,包括大括号的使用、空格和缩进的要求、注释格式、强制转换和单行字符数限制等方面,旨在提高代码的可读性和一致性。此外,还强调了OOP编程的一些重要原则,如避免直接通过对象访问静态变量、使用@Override注解、避免修改已发布的接口签名等,以确保代码质量与稳定性。
摘要由CSDN通过智能技术生成

Java开发手册-2

代码格式

  1. 【强制】如果大括号内为空,简洁地写成{},大括号中间无需换行和空格;如果是非空代码块,则:
    (1)左大括号前不换行。 (2)左大括号后换行。 (3)右大括号前换行。
    (4)右大括号后还有else等代码则不换行;表示终止的右大括号后必须换行。

  2. 【强制】左小括号和右边相邻字符之间不需要空格;右小括号和左边相邻字符之间也不需要空格;而左大括号前需要加空格。
    反例:if (空格a == b空格)

  3. 【强制】if/for/while/switch/do等保留字与左右括号之间都必须加空格。

  4. 【强制】任何二目、三目运算符的左右两边都需要加一个空格。 说明:包括赋值运算符=、逻辑运算符&&、加减乘除符号等。

  5. 【强制】采用4个空格缩进,禁止使用Tab字符。 说明:如使用Tab缩进,必须设置1个Tab为4个空格。IDEA设置Tab为4个空格时,请勿勾选Use tab character。 正例:(涉及上述中的1-5点)

    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"); 		//在右大括号后直接结束,则必须换行广 	} } ```
    
  6. 【强制】注释的双斜线与注释内容之间有且仅有一个空格。 正例:

    String("demo"); ```
    
  7. 【强制】在进行类型强制转换时,右括号与强制转换值之间不需要任何空格隔开。 正例:

    java double first = 3.2D; int second = (int)first+2;

  8. 【强制】单行字符数限制不超过120个,超出需要换行,换行时遵循如下原则:
    (1)第二行相对第一行缩进4个空格,从第三行开始,不再继续缩进,参考示例。
    (2)运算符与下文一起换行。
    (3)方法调用的点符号与下文一起换行。
    (4)方法调用中的多个参数需要换行时,在逗号后进行。
    (5)在括号前不要换行。
    正例:

    //超过120个字符的情况下,换行缩进4个空格,并且方法前的点号一起换行
    builder.append("yang").append("hao")... 	.append("chen")... 
    	.append("chen")...  	.append("chen"); ```
    
    <font color =A52A2A>反例:</font>
    
    ```java StringBuilder builder = new
    StringBuilder();//超过120个字符的情况下,不要在括号前换行 builder
    append("you").append("are")...append ("lucky");
    //参数很多的方法调用可能超过120个字符,逗号后才是换行处 method(args1,args2,args3,… ,argsX);
    
  9. 【强制】方法参数在定义和传入时,多个参数逗号后面必须加空格。 正例:下例中实参的args1逗号后边必须要有一个空格。

```java method(args1, args2, args3); ```
  1. 【强制】IDE的text file encoding设置为UTF-8;IDE中文件的换行符使用Unix格式,不要使用Windows格式。
  2. 【推荐】不同逻辑、不同语义、不同业务的代码之间插入一个空行,分隔开来以提升可读性。 说明:任何情形,没有必要插入多个空行进行隔开。

OOP规约

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

  2. 【强制】所有的覆写方法,必须加@Override注解。 说明:getObjec()getObject()的问题。一个是字母的O,一个是数字的0,加@Override可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。

  3. 【强制】外部正在调用的接口或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生影响。接口过时必须加@Deprecated注解,并清晰地说明采用的新接口或者新服务是什么。

  4. 【强制】Objectequals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals
    正例:"test".equals(param); Cparam.equals("test");
    说明:
    推荐使用JDK7引入的工具类java.util.Objects#equals(Object a,Object b)**

  5. 【强制】所有整型包装类对象之间值的比较,全部使用equals方法比较。
    说明:对于Integer var=?-128127之间的赋值,Integer对象是在 IntegerCache.cache
    产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用
    equals 方法进行判断。

  6. 【强制】任何货币金额,均以最小货币单位且为整型类型进行存储。

  7. 【强制】浮点数之间的等值判断,基本数据类型不能使用==进行比较,包装数据类型不能使用equals进行判断。

    说明:
    浮点数采用“尾数+阶码”的编码方式,类似于科学计数法的“有效数字+指数”的表示方式。二进制无法精确表示大部分的十进制小数,具体原理参考《码出高效》。反例:

    	//预期进入此代码块,执行其它业务逻辑 	//但事实上a==b的结果为false  } Float x =
    Float.valueOf(a); Float y = Float.valueOf(b); if (x.equals(y) {
    	//预期进入此代码块,执行其它业务逻辑 	//但事实上equals的结果为false } ```<font color
    =#228B22>正例:</font>1)指定一个误差范围,两个浮点数的差值在此范围之内,则认为是相等的。
    
    ```java float a = 1.0F-0.9F; float b = 0.9F-0.8F; float diff =
    1e-6F; if (Math.abs(a - b) < diff) { 	System.out.println("true"); }
    

    (2)使用 Big Decimal来定义值,再进行浮点数的运算操作。

    BigDecimal("0.9"); BigDecimal c = new BigDecimal("0.8"); BigDecimal
    x = a.subtract(b); BigDecimal y = b.subtract(c);
    
    if (x.compareTo(y) == 0) { 	System out.println("true"); } ```
    
  8. 【强制】BigDecimal的等值比较应使用compareTo()方法,而不是equals()方法。

    说明:
    equals()方法会比较值和精度(1.01.00返回结果为false),而compareTo()则会忽略精度。

  9. 【强制】定义数据对象DO类时,属性类型要与数据库字段类型相匹配。
    正例:数据库字段的 bigint 必须与类属性的Long类型相对应。
    反例:某业务的数据库表id 字段定义类型为bigint unsigned,实际类对象属性为
    Integer,随着id越来越大,超过Integer的表示范围而溢出成为负数,此时数据库id不支持存入负数抛出异常产生线上故障。

  10. 【强制】禁止使用构造方法BigDecimal(double)的方式把 double 值转化为BigDecimal对象
    说明:
    BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。如:BigDecimal g = new Big Decimal(0.1F);实际的存储值为:0.100000001490116119384765625
    正例:优先推荐入参为String的构造方法,或使用
    BigDecimalvalueOf方法,此方法内部其实执行了
    DoubletoString,而DoubletoString
    double的实际能表达的精度对尾数进行了截断。

    recommend2 = BigDecimal.valueOf(0.1); ```
    
  11. 关于基本数据类型与包装数据类型的使用标准如下:
    (1)【强制】所有的POJO类属性必须使用包装数据类型。
    (2)【强制】RPC方法的返回值和参数必须使用包装数据类型。
    (3)【推荐】所有的局部变量使用基本数据类型。
    说明:POJO类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何NPE问题,或者入库检查,都由使用者来保证。
    正例:数据库的查询结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险。
    反例:某业务的交易报表上显示成交总额张跌情况,即正负×%×为基本数据类型,调用的RPC服务,调用不成功时,返回的是默认值,页面显示为0%,这是不合理的,应该显示成中划线-。所以包装数据类型的
    null值,能够表示额外的信息,如:远程调用失败,异常退出。

  12. 【强制】定义DO/PO/DTO/VOPOJO类时,不要设定任何属性默认值。 反例:某业务的DOcreateTime默认值为new Date();但是这个属性在数据提取时并没有置入具体值,在更新其它字段时又附带更新了此字段,导致创建时间被修改成当前时间。

  13. 【强制】序列化类新增属性时,请不要修改serialVersionUID字段,避免反序列失败;如果完全不兼容升级,避免反序列化混乱,那么请修改
    serialVersionUID值。
    说明:
    注意serialVersionUID不一致会抛出序列化运行时异常。

  14. 【强制】构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在init方法中。

  15. 【强制】POJO类必须写toString方法。使用IDE中的工具source>generate toString 时,如果继 承了另一个POJO类,注意在前面加一下super.toString()
    说明:
    在方法执行抛出异常时,可以直接调用POJOtoString()方法打印其属性值,便于排查问题。

  16. 【强制】禁止在POJO类中,同时存在对应属性xxxisXxx()getXxx()方法。

    说明:
    框架在调用属性×××的提取方法时,并不能确定哪个方法一定是被优先调用到,神坑之一。

  17. 【推荐】使用索引访问用Stringsplit方法得到的数组时,需做最后一个分隔符后有无内容的检查,否则会有抛IndexOutOfBoundsException的风险。
    说明:

    //预期大于3,结果等于3  System.out.println(ary.length); ```
    
  18. 【推荐】当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起,便于阅读,此条规则优先于下一条。
    正例:

    param 1, int param2); private void method(); ```
    
  19. 【推荐】类内方法定义的顺序依次是:公有方法或保护方法>私有方法>getter/setter方法。
    说明:
    公有方法是类的调用者和维护者最关心的方法,首屏展示最好;保护方法虽然只是子类关心,也可能是"模板设计模式”下的核心方法;而私有方法外部一般不需要特别关心,是一个黑盒实现;因为承载的信息价值较低,所有ServiceDAOgetter/setter方法放在类体最后。

  20. 【推荐】setter方法中,参数名称与类成员变量名称一致,this.成员名 = 参数名。在getter/setter方法中,不要增加业务逻辑,增加排查问题的难度。 反例:

    this.data + 100; 	} else { 		return this.data - 100; ```
    
  21. 【推荐】循环体内,字符串的连接方式,使用StringBuilderappend方法进行扩展。 反例:

    str + "hello"; } ```
    
    <font color =#CD853F> 说明:</font>反编译出的字节码文件显示每次循环都会`new`
    出一个`StringBuilder`对象,然后进行`append`操作,最后通过`toString()`返回`String`对象,造成内存资源浪费。
    
  22. 【推荐】final可以声明类、成员变量、方法、以及本地变量,下列情况使用final关键字: (1)不允许被继承的类,如:String类。 (2)不允许修改引用的域对象,如:POJO类的域变量。
    (3)不允许被覆写的方法,如:POJO类的setter方法。 (4)不允许运行过程中重新赋值的局部变量。
    (5)避免上下文重复使用一个变量,使用final关键字可以强制重新定义一个变量,方便更好地进行重构。

  23. 【推荐】慎用Objectclone方法来拷贝对象。
    说明:
    对象clone方法默认是浅拷贝,若想实现深拷贝需覆写clone方法实现域对象的深度遍历式拷贝。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值