在本文中,您将了解每个 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 的可能性。