列举一些 Java 开发中常见的“不良实践”,来源于代码扫描(https://github.com/pmd/pmd),和诸君一起学习参考:
1 - 关闭资源
CloseResource: Ensure that resources like this FileInputStream object are closed after use.
确保 FileInputStream、HttpClient 之类的对象在使用后被及时关闭。
JDK 1.8 开始建议使用 try-with-resource
关闭资源,因为对于多个资源或异常的捕获中,try-finally 可能丢失掉前面的异常,而 try-with-resource 会保留第一个异常,并把后续的异常作为Suppressed exceptions,可通过 getSuppressed()
返回的数组来检验。
try-with-resource 示例:
try (FileReader fileReader = new FileReader(filePath);
BufferedReader bfReader = new BufferedReader(fileReader)) {
// do something
}
2 - 松耦合
LooseCoupling: Avoid using implementation types like 'ArrayList', use the interface instead.
避免使用具体的实现类型,比如“ArrayList”,而是使用它们的接口,比如:
// 这种方法不好:
public ArrayList<String> getList() {
ArrayList<String> list = new ArrayList<String>();
// do something
return list;
}
// 建议这样用:
public List<String> getList() {
List<String> list = new ArrayList<String>();
// do something
return list;
}
第二种写法的优点是,这个方法的调用者不必关注方法内部到底使用了哪个 List<String>
的具体实现,并且就算方法内部的实现发生了变化,调用方也不需要修改自己的代码。
3 - 避免捕获NPE
AvoidCatchingNPE - Avoid catching NullPointerException, consider removing the cause of the NPE.
避免捕获空指针异常,考虑删除相关的捕获语句,并在代码中进行空引用的检查。
程序在运行期抛出 NullPointException 异常,表明存在一个对空指针的解引用,这类问题应该在代码中解决。
通过捕获 NullPointException 异常而不对根本原因进行处理是不合适的:
1)捕获 NullPointException 而不是作简单的空引用检查,在性能上要付出更大的代价;
2)当 try 程序段中多个表达式都有可能抛出 NullPointException 时,无法正确判断异常的抛出位置;
3)程序抛出 NullPointException 异常很少会处于正常的可用状态。
4 - 使用 equals() 方法来比较 String 类型
UseEqualsToCompareStrings - Use equals() to compare strings instead of '==' or '!='.
使用 equals() 方法对 String 类型进行比较,而不是用 “==” 或 “!=”。
这是为了防止比较的对象是通过 new String("") 构造的,== 比较的是对象的地址,要注意这点。
5 - 使用 “==” 判断实例是否为 null
EqualsNull - Avoid using equals() to compare against null.
使用 “==” 判断实例是否为 null ,如:str == null
,而不是 str.equals(null)
。
6 - 避免打印堆栈信息
AvoidPrintStackTrace - Avoid printStackTrace(), use a logger call instead.
避免使用 printStackTrace()
方法直接打印堆栈,而是要使用日志框架打印堆栈信息。
7 - Integer 类型的初始化
IntegerInstantiation - Avoid instantiating Integer objects. Call Integer.valueOf() instead.
避免通过 new Integer(param)
直接创造 Integer 对象,推荐用:Integer.valueOf(param)
的方法来创建。
如果是 String 类型的参数,推荐用 Integer.parseInt()
方法,解析生成对应的数值类型,更高效。
其他类型(比如 Boolean\Long、 Double)的解析,修改方式和 Integer 相同。
8 - Boolean 类型的初始化
BooleanInstantiation - Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead.
避免创建 Bool 类型的对象,比如 new Boolean(false)
,建议使用全局的 Boolean 实例。
由于 Boolean 类型就只有 1 / 0 两种状态,因此建议通过 Boolean.TRUE
或 Boolean.FALSE
,或 Boolean.valueOf()
来使用。
参考资料
版权声明
出处:博客园-瘦风的南墙(https://www.cnblogs.com/shoufeng)
感谢阅读,公众号 「瘦风的南墙」 ,手机端阅读更佳,还有其他福利和心得输出,欢迎扫码关注