每个 Java 开发人员今天必须避免的 15 + 11 个错误

文摘   科技   2024-05-08 12:45   中国台湾  

在本文中,您将了解每个 Java 开发人员都应该掌握的 11 种最重要的干净代码实践(好与坏)。

1. 整数乘法和除法的移位运算符

不良实践:使用传统方式进行涉及 2 的幂的运算

  • 这里,乘法和除法是使用 * 和 / 运算符显式执行的。

  • 这种方法效率较低,尤其是在处理 2 的幂时。

良好实践:使用左移和右移运算符

  • 使用移位运算(<< 用于乘法,>> 用于除法)使代码更高效、优化性能。

  • 这在涉及 2 的幂的运算中最有用。

2. 使用 String.valueOf() 进行最佳字符串转换

不好的做法:使用 + 运算符进行字符串连接。

  • 这里,‘+’运算符用于字符串转换,这涉及到隐式字符串连接。

  • 这种方法可能效率低下,尤其是在将大量变量转换为字符串时。

良好实践:使用内置方法进行字符串连接。

  • 在这里,我们使用 valueOf() 进行字符串转换和连接。

  • 此方法专门用于将其他数据类型转换为字符串,并针对性能进行了优化。

3.使用System.arraycopy复制数组

不好的做法:手动复制数组

  • 这种方法效率较低,特别是对于大型数组,因为它涉及多次迭代和元素分配。

良好实践:使用 System.arraycopy() 或 Arrays.copyOf() 复制数组

  • 这里,一行代码将所有元素从 sourceArray 复制到 targetArray。

  • 它在较低级别上运行,使其比通过数组进行手动迭代更有效。

4. 使用 isEmpty() 检查空集合

不好的做法:使用 length() 或 size() 来检查字符串或集合是否为空。

  • 这里,length() 用于检查字符串是否为空,size() 用于检查集合是否为空。

  • 这些方法虽然有效,但会降低代码的可读性。

良好实践:使用 isEmpty() 检查字符串或集合是否为空。

  • isEmpty() 方法可用于字符串和集合来检查是否为空。

  • 它的时间复杂度为 O(1),使其更加高效和可读。

5. 最小化循环内的异常处理

不良实践:处理循环内的异常

  • 这种方法降低了效率,特别是当循环迭代大型集合并频繁引发异常时。

  • 如果循环在遇到异常时终止,则可能不需要在循环中捕获异常。

良好实践:处理循环外的异常

  • 在这里,如果发生异常,循环可以继续执行,并确保捕获循环内抛出的异常。

6. 预编译正则表达式

不好的做法:在运行时编译正则表达式

  • 在这里,无论何时使用正则表达式,都会在运行时对其进行编译。

  • 当重复使用相同的正则表达式时,会降低性能。

良好实践:预编译和重用正则表达式

  • 通过预编译重复的正则表达式,然后在需要的地方重用它,我们可以避免冗余编译并提高性能。

7. 避免在检索之前预先检查数据是否存在

不良做法:

  • 在这里,我们首先检查 id 是否存在于地图中,然后再检索它。

  • 这种预检查是不必要的,因为如果未找到键,映射的 get 方法将返回 null。

良好实践:

  • 这里,我们直接使用 get 方法从地图中检索 id,然后检查角色是否不为 null。

  • 这种方法避免了冗余检查,并产生更干净、更高效的代码。

8.集合到数组的高效转换

不良做法:

  • 在这种方法中,首先计算列表的大小,然后创建一个新数组。

  • 这可能会影响性能,尤其是对于大型集合。

良好实践:

  • 此处,使用空数组 (new String[0]) 调用 toArray。

  • 这种方法避免了计算列表大小的需要,并允许 toArray 方法在内部处理数组大小调整,从而获得更好的性能和更干净的代码。

9. 使用默认方法

不良做法:

  • 如果需要将新方法(例如 logError)添加到接口中,则必须修改所有实现类,这可能会导致代码维护问题和潜在错误。

良好实践:

  • 这里,Logger接口定义了一个默认方法(logError),它提供了记录错误的默认实现。实现类会自动继承此默认实现,无需进行修改。

10.使用日期/时间API

不良做法:

  • 该类存在各种问题,例如其方法的可变性和缺乏清晰度。

  • 此类中的大多数方法(例如 getYear()、getMonth() 和 getDay())均已弃用。

良好实践:使用日期/时间 API 中的类(Java 8 及以上)

  • 在这里,我们使用日期/时间 API 中的 LocalDate 类。

  • LocalDate 是不可变的,确保了线程安全,并为日期操作提供了清晰直观的方法。

11.正确使用wait()/notify()

不良做法:

  • 这里,notify() 调用是在不检查是否有任何线程实际上正在等待锁的情况下进行的。

  • 此类中的大多数方法(例如 getYear()、getMonth() 和 getDay())均已弃用。

好的实践:使用notifyAll()而不是notify()

  • notifyAll() 安全地通知所有等待线程,并且如果没有线程正在等待则无效,从而防止出现 IllegalMonitorStateException 的可能性。

好吧,恭喜您读完本文。

推荐阅读

全栈开发ck
叩首问路,码梦为生