高效能团队的Java研发规范(icode9进阶版)


目前大部分团队是使用的阿里巴巴Java开发规范,不过在日常开发中难免遇到覆盖不到的场景,本文在阿里巴巴Java开发规范基础上,补充一些常用的规范,用于提升代码质量及增强代码可读性。

编程规约

1、基础类型及操作

(1)转换

基本类型转换

String类型转数字:使用apache common-lang3包中的工具类NumberUtils,优势:可设置默认值,转换出错时返回默认值

NumberUtils.toInt("1");

拆箱:包装类转化为基本类型的时候,需要判定null,比如:

Integer numObject = param.get(0);
int num = numObject != null ? numObject : 0;
对象类型转换

使用MapStruct工具,转换类后缀Convertor,所有转换操作都在转换类中操作,禁止在业务代码中编写大量set代码。

(2)判断

枚举判定

使用枚举判等,而非枚举对应的数字。因为枚举更直观,方便查看代码及调试,数字容易出错。

判空

各种对象的判空:

//对象判空&非空
Objects.isNull()
Objects.nonNull()

//String判空&非空
StringUtils.isEmpty()   //可匹配null和空字符串
StringUtils.isNotEmpty()
StringUtils.isBlank()   //可匹配null、空字符串、多个空白字符
StringUtils.isNotBlank()

//集合判空&非空
CollectionUtils.isEmpty()
CollectionUtils.isNotEmpty()

//Map判空&非空
MapUtils.isEmpty()
MapUtils.isNotEmpty()
断言

使用Guava里的Preconditions工具类,比如:

//如果是空则抛异常
Preconditions.checkNotNull()
//通用判断
Preconditions.checkArgument()

2、集合处理

(1)Map快捷操作

推荐:

//如果值不存在则计算
map.computeIfAbsent("key",k-> execValue(k));
//默认值
map.getOrDefault("key", DEFAULT_VALUE)

反例:

//如果值不存在则计算
String v = map.get("key");
if(v == null){
    v = execValue("key");
    map.put("key", v);
}
//默认值
map.containsKey("key") ? map.get("key") : DEFAULT_VALUE

(2)创建对象

构造方法或Builder模式,超过3个参数对象创建使用Builder模式

//Java11+:
List.of(1, 2, 3)  
Set.of(1, 2, 3)
Map.of("a", 1)

//Java8中不可变集合(需引入Guava)
ImmutableList.of(1,2,3)
ImmutableSet.of(1,2,3)
ImmutableMap.of("key","value")
//多值情况
ImmutableMap.builder()
    .put("key", "value")
    .put("key2", "value2")
    .build()

//Java8中可变集合(需引入Guava)
Lists.newArrayList(1, 2, 3)
Sets.newHashSet(1, 2, 3)
Maps.newHashMap("key", "value")

反例:

new ArrayList<>(){{
   add(1);
   add(2);
}};

(3)集合嵌套

集合里的值如果是基础类型必须加上注释,说明集合里存的是什么,比如:

//返回值: Map(key: 姓名, value: List(商品))
Map<String, List<String>> res;

超过2层集合对象封装必须封装成自定义类:

//推荐
Map<String, List<Node>> res;

@Value
public static class Node {
    /**
    * 备注说明字段
    */
    String name;
    /**
    * 备注说明字段2
    */
    List<Integer> subjectIds;
}

//反例
Map<String, List<Pair<String, List<Integer>>>> res;

异常及日志

1、异常

异常除了抛异常还有一种场景,即:上层发起多个必要调用,某些可能失败,需要上层自行决定处理策略,推荐使用vavr中的Either类,Either使用建议:通常我们使用左值表示异常,而右值表示正常调用后的返回结果,即: Either<Throwable, Data>

2、日志

(1)日志文件

根据日志等级一般分为4个日志文件即可:debug.log、info.log、warn.log、error.log;

如有特殊需求可根据场景单独建文件,比如请求日志:request.log、gc日志:gc.log等。

(2)所有用户日志都要有追踪字段

追踪字段包括:traceId、userId等,推荐使用MDC,常用的日志框架:Log4j、Logback都支持。

(3)日志清理及持久化

本地日志根据磁盘大小,必须设置日志保存天数,否则有硬盘满风险;

分布式环境为了方便查询,需要将日志采集到ES中查询;

重要日志:比如审计日志、B端操作日志需要持久保存,一般是保存到Hive中;

本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;

2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;

3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;

4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;

5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/294375.html

(0)
上一篇 2022年12月1日 17:10
下一篇 2022年12月1日 17:10

相关推荐

发表回复

登录后才能评论