# 代码编写规范 ## Java的新特性 目前主流的JDK选型有4个版本:8、17、21、25。通过`pom.xml`中的``标签可以定位当前项目的JDK版本是多少。积极的使用新特性,例如:局部变量类型推断、Switch表达式、模式匹配、文本块、记录类、虚拟线程。**虚拟线程应当用于IO密集型的任务,而不是CPU密集型任务。** ## 必须恪守的基本原则 - 一个Java源文件的行数**不得超过300行**,否则拆成多个文件。 - 一个方法的行数**不得超过20行**,否则拆成多个方法。 - 积极使用`Optional`处理NULL值,避免大量的`if (obj != null)`。 - 优先使用`Stream`,若`map`或`flatMap`代码块**超过5行**就单独写一个方法。如果`map`代码块需要中间对象且JDK版本高于17,则优先使用记录类,否则退化到普通java类,记录类和DTO存放在一个目录。 - 构建JavaBean对象,优先使用构造函数而不是单独写方法,**只有3个以内的属性,应提供一个全部参数的构造函数**。 - 只在关键地方插入简洁的注释,不啰嗦、不废话、不长篇大论。尽量用清晰明确的命名,避免添加注释。 ## 三方库的使用原则 - 如果项目引入了`Lombok`,请积极使用,无需担心编译速度被拖慢。 - 如果项目引入了`hutool`,请尽量少写工具类,最大程度复用`hutool-core`、`hutool-json`、`hutool-system`模块中的工具,其他模块的包慎用!当JDK版本高于11,不得引入`hutool-http`工具包,使用JDK内置的`HttpClient`替代,可以新建一个`HttpUtils`减少代码冗余。 - 如果项目引入了`jackson`,`ObjectMapper`或`JsonMapper`应该单例使用,且基于`jackson`新建1个`JsonUtils`去替代`hutool-json`是更好的选择。但不能创建多个`JsonUtils`,能复用则复用。 ## 集合与队列 | 集合工具 | 何时使用 | | --- | --- | | ArrayList | 在非多线程场景使用。
方法返回空集合使用`Collections.emptyList()`。
如果是`Dubbo`接口的返回值,空集合要使用`new ArrayList<>()`。| | HashSet | 在非多线程且**没有排序要求**的场景使用。
方法返回空集合使用`Collections.emptySet()`。
如果是`Dubbo`接口的返回值,空集合要使用`new HashSet<>()`。| | HashMap | 在非多线程且**没有排序要求**的场景使用。
方法返回空集合使用`Collections.emptyMap()`。
如果是`Dubbo`接口的返回值,空集合要使用`new HashMap<>()`。| | LinkedHashSet、LinkedHashMap | 在非多线程且**需要按照插入顺序遍历**的场景使用。| | TreeSet、TreeMap | 在非多线程场景且**有排序要求**的场景使用。| | ConcurrentSkipListSet | 在需要排序的场景且多线程安全的场景使用。| | CopyOnWriteArraySet | 读多写少、无需排序、集合的规模较少,比如:监听器、回调注册表。 | | ConcurrentHashMap | 在多线程场景且**无排序要求**的场景下使用。| | ConcurrentSkipListMap | 在多线程场景且**有排序要求**的场景下使用。| | ArrayBlockingQueue | 在多线程**需限制内存、容量固定、延迟可预测**的场景下使用 | | LinkedBlockingQueue | 在多线程**需高吞吐、长度波动大、生产消费并发高**的场景下使用,**必须显式指定容量,防止OOM**。| ## Lock的使用规范 - 单机环境下,使用`ReentrantLock`或者`StampedLock`。 - 分布式环境下,如果`pom.xml`中引入了`Redisson`,则应该优先使用`RedissonClient`。