检查所有功能中的所有功能参数

时间:2009-07-30 13:33:03

标签: java validation parameters function

当我第一次从c转到Java时,我认为我已经完成了所有烦人的参数检查,在每个函数的开头。 (有福的例外)

最近我意识到我正在慢慢地再次回到那种做法,我开始对所有的

感到非常生气
if (null == a || null == b || null == a.getValue() || ...) 
{
  return null;
}

例如,我有一个实用工具类,用于分析网页并从中提取特定元素。用null元素调用dom对象函数通常会导致异常 - 所以在我在这个类中编写的几乎所有函数中都有无数的null检查:

private URL extractUrl(Element element) throws Exception {
if (null == element) {
  return null;
} ... 

public List<Object> getConcreteElements(String xpath) throws Exception {
if (null == xpath) {
  return Collections.emptyList();
}...

public String getElementsAsXML(String xpath) throws Exception {
if (null == xpath) {
 return null;
}...

在每个功能的开头。这是我应该习惯的东西,还是有一些我不知道的编码习惯可以简化我的生活?

6 个答案:

答案 0 :(得分:7)

返回null意味着调用者必须始终检查方法的结果。意思是更悲惨的空检查。

请考虑使用NullObject模式,返回有效对象但具有空操作。即如果返回集合或类似的空列表。

答案 1 :(得分:4)

在组件的公共边界,您总是必须进行数据验证。

对于内部方法,assert传递的值是正确的更好。

如果可以的话,返回null是最好避免的。要么失败那么在那里表示你上游有一个错误(内部情况)或者如果有这样的东西可以返回一个空的或默认的对象(公共情况)。

答案 2 :(得分:2)

是的,他们真的很讨厌。我发现一些小事情至少可以减少这个:

  • 清楚地记录内部api的函数,这些函数不能返回null,或者在什么条件下你可以期望null。如果您可以信任您的文档,至少可以避免在某些地方进行空检查。
  • 一些习语最小化空检查 - 例如

    if(string!= null&amp;&amp; string.equals(“A”) - &gt; if(“A”.equals(string))

  • eclipse(以及findbugs,我认为,可能还有许多其他ide)可以设置为标记冗余空检查或缺少空检查。不完美,但它有所帮助。

但总的来说,你是对的。如果我的代码没有空检查和记录语句,那么根本就没有任何东西;)

答案 3 :(得分:1)

如果对您的应用程序有意义,则只检查null-return-null。可能是返回null只会导致客户端代码出现问题,而客户端代码不会出现空值。可能是因为输入错误而没有合理的返回值,在这种情况下使用例外。

至于你是否应该检查参数,这取决于谁在使用该功能。如果它是私人功能,检查可能有点过分。如果它是一个公共API函数,你绝对应该检查。

答案 4 :(得分:1)

根据我的经验,如果任何API的默认“合同”是null参数值且不允许null结果,则Java应用程序更易于维护。如果方法设计为允许null参数或返回null,则应在Javadoc中明确指定含义和环境。

如果传递了null,而API没有明确允许这样做,那么这是一个错误,最好的办法是使用NPE快速失败。 (国际海事组织,没有必要记录NPE的可能性......可以假设。)如果null不是一个有意义的(记录的)参数值,那么测试null和返回null仅用于传播错误数据并使调试代码变得更加困难。如果你的方法使用提供的null参数并导致NPE,那就这样吧。如果不使用参数但它保存了值以供将来使用,那么值得测试null并显式抛出NPE。

我还尝试避免使用null来表示空列表或空数组的(通常是错误的)优化,至少在API级别。

现在有些情况下API设计使用null s是有意义的;例如在API中,对象参数实现某种插件行为/策略,或者在未提供可选方法参数时使用null。但你需要考虑并记录它。

答案 5 :(得分:1)

如果您检查非法值,请不要犹豫,抛出IllegalArgumentExceptions以通知调用者他犯了错误。您可以隐藏私有方法中的边界/非法值检查,这样可以提高代码的可读性,例如 - 只需要一个示例:

private URL extractUrl(Element element) throws Exception {

  validateExactUrlParameter(element);

  // the real url extraction code

}

private static validateExactUrlParameter(Element element) 
                              throws IllegalArgumentException {

  if (null == element) {
    throw new IllegalArgumentException("Null value not allowed for exactUrl method");
  }

  // do some more checks here, if required

}

如果你想避免try / catch块,那么考虑抛出未经检查的异常(RuntimeException或自定义子类)。