Java 编码规范-对自己经常犯的

本文详细阐述了Java编码过程中的关键规范,包括数据类型的选用、代码格式化、枚举类型设计、异常处理策略、参数校验准则及并发场景下的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

2. 【强制】单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:
1) 第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。
2) 运算符与下文一起换行。
3) 方法调用的点符号与下文一起换行。
4) 方法调用中的多个参数需要换行时,在逗号后进行。
5) 在括号前不要换行,见反例。
正例:
StringBuffer sb = new StringBuffer(); 
// 超过 120 个字符的情况下,换行缩进 4 个空格,点号和方法名称一起换行
sb.append("zi").append("xin")... 
.append("huang")... 
.append("huang")... 
.append("huang");
反例:
StringBuffer sb = new StringBuffer(); 
// 超过 120 个字符的情况下,不要在括号前换行
sb.append("zi").append("xin")...append 
("huang"); 
// 参数很多的方法调用可能超过 120 个字符,不要在逗号前换行
method(args1, args2, args3, ... 
, argsX); 

 

3. 【强制】采用 4 个空格缩进,禁止使用 tab 字符。
说明:如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。IDEA 设置 tab 为 4 个空格时,
请勿勾选 Use tab character;而在 eclipse 中,必须勾选 insert spaces for tabs

 

4. 【推荐】如果变量值仅在一个固定范围内变化用 enum 类型来定义。
说明:如果存在名称之外的延伸属性应使用 enum 类型,下面正例中的数字就是延伸信息,表
示一年中的第几个季节。
正例:
public enum SeasonEnum {
 SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);
 private int seq;
 SeasonEnum(int seq){
 this.seq = seq;
 }
}

 

5. 【强制】定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值。反例:POJO 类的 gmtCreate 默认值为 new Date(),但是这个属性在数据提取时并没体值,在更新其它字段时又附带更新了此字段,导致创建时间被修改成当前时间

 

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

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

 

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

9. 【推荐】类成员与方法访问控制从严:
1) 如果不允许外部直接通过 new 来创建对象,那么构造方法必须是 private。
2) 工具类不允许有 public 或 default 构造方法。
3) 类非 static 成员变量并且与子类共享,必须是 protected。
4) 类非 static 成员变量并且仅在本类使用,必须是 private。
5) 类 static 成员变量如果仅在本类使用,必须是 private。
6) 若是 static 成员变量,考虑是否为 final。
7) 类成员方法只供类内部调用,必须是 private。
8) 类成员方法只对继承类公开,那么限制为 protected。
说明:任何类、方法、参数、变量,严控访问范围。过于宽泛的访问范围,不利于模块解耦。
思考:如果是一个 private 的方法,想删除就删除,可是一个 public 的 service 成员方法或
成员变量,删除一下,不得手心冒点汗吗?变量像自己的小孩,尽量在自己的视线内,变量作
用域太大,无限制的到处跑,那么你会担心的。

9. 【强制】不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator
方式,如果并发操作,需要对 Iterator 对象加锁。
正例:
 

List<String> list = new ArrayList<>(); 
list.add("1"); 
list.add("2"); 
Iterator<String> iterator = list.iterator(); 
while (iterator.hasNext()) { 
    String item = iterator.next(); 
    if (删除元素的条件) { 
        iterator.remove(); 
    } 
}

反例:
 

for (String item : list) { 
    if ("1".equals(item)) { 
        list.remove(item); 
    } 
} 

说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的
结果吗?(线程异常)

 

10.【强制】在高并发场景中,避免使用”等于”判断作为中断或退出的条件。
说明:如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,使用大于或小于的区间
判断条件来代替。
反例:判断剩余奖品数量等于 0 时,终止发放奖品,但因为并发处理错误导致奖品数量瞬间变
成了负数,这样的话,活动无法终止

 

11.【推荐】表达异常的分支时,少用 if-else 方式,这种方式可以改写成:
if (condition) { 
 ... 
 return obj; 

// 接着写 else 的业务逻辑代码; 
说明:如果非得使用 if()...else if()...else...方式表达逻辑,【强制】避免后续代码维
护困难,请勿超过 3 层。
正例:超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现,
其中卫语句示例如下:
public void today() {
 if (isBusy()) {
System.out.println(“change time.”);
 return;
 }
 if (isFree()) {
System.out.println(“go to travel.”);
 return;
 }
System.out.println(“stay at home to learn Alibaba Java Coding Guidelines.”);
 return;
}

 

12【推荐】除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将
复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。
说明:很多 if 语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能明确什么
样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?
正例:
// 伪代码如下
final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
 ...

反例:
if ((file.open(fileName, "w") != null) && (...) || (...)) {
 ...
}

13.【参考】下列情形,需要进行参数校验:
1) 调用频次低的方法。
2) 执行时间开销很大的方法。此情形中,参数校验时间几乎可以忽略不计,但如果因为参
数错误导致中间执行回退,或者错误,那得不偿失。
3) 需要极高稳定性和可用性的方法。
4) 对外提供的开放接口,不管是 RPC/API/HTTP 接口。
5) 敏感权限入口。

14.【参考】下列情形,不需要进行参数校验:
1) 极有可能被循环调用的方法。但在方法说明里必须注明外部参数检查要求。
2) 底层调用频度比较高的方法。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底
层才会暴露问题。一般 DAO 层与 Service 层都在同一个应用中,部署在同一台服务器中,所
以 DAO 的参数校验,可以省略。
3) 被声明成 private 只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参
数已经做过检查或者肯定不会有问题,此时可以不校验参数

15. 【强制】获取当前毫秒数 System.currentTimeMillis(); 而不是 new Date().getTime();
说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime()的方式。在 JDK8 中,
针对统计时间等场景,推荐使用 Instant 类

16. 【推荐】及时清理不再使用的代码段或配置信息。
说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。
正例:对于暂时被注释掉,后续可能恢复使用的代码片断,在注释代码上方,统一规定使用三
个斜杠(///)来说明注释掉代码的理由。 

 

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值