检查NULL是好的还是坏的做法?

时间:2011-12-01 19:30:41

标签: java exception-handling programming-languages null

我见过的代码几乎检查了所有应用程序层中的每个变量都不是null。我也看到了代码几乎没有这个。

if(object != null){}

检查变量是否为NULL的最佳做法是什么?它真正有意义,并且NullPointerException确实是一件坏事 - 所有这些null检查可能是您的应用程序健康状况不佳的症状吗?

4 个答案:

答案 0 :(得分:6)

明确检查null是个好主意,因为:

  • 您可以提前发现错误。
  • 您可以提供更具描述性的错误消息。

如果你得到NullPointerException,你可能无法确切地知道哪个变量为空。即使你有抛出异常的行号,该行上仍可能有多个变量。

将这些检查放在公共界面中尤为重要。这是因为当您的用户提供不正确的参数时,他们应该得到IllegalArgumentException告诉他们他们犯了错误。如果他们刚回来NullPointerException他们无法判断他们是否提供了错误的参数,或者您的代码中是否存在错误。

答案 1 :(得分:2)

以下是按重要性排列的一些最佳做法:

  1. 如果可以提供帮助,请不要返回null。例如,如果您的方法返回一个集合,则返回一个空集合而不是null。在某些情况下,Null Object模式可能会有所帮助。但是你必须小心,只使用NullObject可以提供合理的默认行为,而无需额外的if-check。
  2. 如果您的代码可以提供合理的空案例处理,请检查空值。如果你只是在检测到null时抛出另一个异常,那么显式处理null几乎没有价值。
  3. 记录函数的javadoc中返回null的函数的所有实例。 (不幸的是,你不能真正依赖javadoc,但它有助于维持纪律)。

答案 2 :(得分:0)

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就好像它不是 - 这只是简单的错误编码,如果你要去,你不应该初始化它将其设置为null。通常这样做是为了让开发人员可以搜索/评估情况,然后设置值 - 但是如果你的搜索抛出NotFound并且你的存在检查是if块,你的逻辑元素应该阻止你访问空值 - 因为你必须直接分配它。

因为NPE通常来自不良搜索,并且有很多方法可以规避这些包含良好编码实践的失败,所以这种空检查有时被认为是坏习惯。

避免NPE的最好方法是永远不要让null被赋予良好的编码习惯。

所以我的答案是:如果您正在处理错误的代码,请检查空值。你只需要。但如果它是你的所有代码,你永远不应该返回空值或分配它们。

答案 3 :(得分:-3)

变量应在定义时初始化,例如

Object myObject = new Object();

Object myObject;
... // other code that might use myObject
myObject = new Object();

这将消除大多数可能为null的对象。对于对象可能为null的其他情况,检查它是有序的,但这并不意味着您必须检查每个变量。