NullPointerExceptions 很痛苦。它们源于在集合中查找项目(缓存、映射、列表、数据库、文件系统……不胜枚举)并将空值分配给变量或访问它们。
文件系统有一个很好的方法来处理失败的引用——FileNotFoundException——但是,这会被 IOException 所掩盖,所以它不是那么明显和有用。
我发现从 Exception 扩展的这些 *NotFound 异常非常有用,并且广泛使用它们已经消除了我的大部分 NPE。
当我搜索我的数据库或从缓存中查找一个键时,我的查找器通常会抛出一个 NotFound 变体,并且在我的代码中,我知道我可以在哪里有一个通常会破坏我的代码的空值,现在我有了一个位置我可以在哪里记录或处理它。
try{
Record r = table.where(F_ID+"=?",id);
r.doStuff();
}catch(RecordNotFoundException e){
LOG.info("whoops - id " + id + " not found?",e);
}
对于数组或映射等较小的东西,在检查空值之前检查长度或存在。
if(map.contains(id)){
map.get(id).doStuff();
}else{
LOG.info("whoops - id " + id + " not found?",e);
}
if(arr.length < index && arr[index] != null){
arr[index].doStuff();
}else{
LOG.info("whoops - index " + index + " not found?",e);
}
它们来自的另一个地方是来自像“Long id = null”这样的错误实例化,然后引用 id 就好像它不是 - 这只是简单的错误编码,如果你只是要初始化它,你不应该初始化它将其设置为空。通常这样做是为了让开发人员可以搜索/评估情况,然后设置值——但如果你的搜索抛出 NotFound 并且你的存在检查在 if 块中,你的逻辑元素应该阻止你访问空值——因为你必须直接分配它。
因为 NPE 通常来自错误的搜索,并且有一些方法可以规避这些失败,并结合了良好的编码实践,所以 null 检查有时被认为是坏习惯。
避免 NPE 的最佳方法是永远不要为良好的编码习惯分配空值。
所以我的回答是:如果您正在处理错误代码,请检查空值。你只需要。但如果这是你的全部代码,你永远不应该返回空值或分配它们。