如何显示方法是否可以返回null

Len*_*mel 45 java null design-by-contract

在发布这个问题并阅读那个问题,我意识到知道一个方法是否应该返回null是非常重要的,或者如果这被认为是错误条件并且应该抛出异常.还有一个很好的讨论,何时返回'null'或抛出异常.

我正在写一个方法,我已经知道如果我想返回null或抛出异常,表达我的决定的最佳方式是什么,换句话说,记录我的合同?

我能想到的一些方法:

  • 在规格/文档中写下来(任何人都会阅读它吗?)
  • 使它成为方法名称的一部分(正如我在这里建议的那样)
  • 假设抛出异常的每个方法都不会返回null,并且每个执行'not'抛出的方法都可能返回null.

我主要讨论java,但它也可能适用于其他语言:为什么有一种正式的方式来表达是否会抛出异常(throws关键字)但是没有正式的方式来表达是否可能返回null?

为什么没有这样的东西:

public notnull Object methodWhichCannotReturnNull(int i) throws Exception
{
    return null; // this would lead to a compiler error!
}
Run Code Online (Sandbox Code Playgroud)

总结和结论

表达合同的方式有很多种:

  • 如果您的IDE支持它(作为IntelliJ),最好使用注释,@NotNull因为它对程序员可见,并且可用于自动编译时检查.Eclipse有一个插件可以添加对这些的支持,但它对我不起作用.
  • 如果这些不是一个选项,请使用类似Option<T>或的自定义类型NotNull<T>,这样可以增加清晰度并至少提高运行时检查.
  • 无论如何,在JavaDoc中记录合同永远不会伤害,有时甚至会有所帮助.
  • 除了我之外,没有人提出使用方法名来记录返回值的可空性,虽然它可能非常详细而且并不总是有用,但我仍然认为它有时也有其优点.

Ron*_*hke 36

一个非常好的跟进问题.我认为null一个真正特殊的值,如果一个方法可能返回null它必须在Javadoc中明确记录(@return some value ..., or null if ...).在编码时我是防御性的,并假设一种方法可能会返回,null除非我确信它不能(例如,因为Javadoc这样说.)

人们意识到这是一个问题,并且建议的解决方案是使用注释以可以自动检查的方式陈述意图.请参阅JSR 305:软件缺陷检测的注释,JSR 308:Java类型的注释JetBrain的Nullable How-To.

您的示例可能如下所示,并被IDE,编译器或其他代码分析工具拒绝.

@NotNull
public Object methodWhichCannotReturnNull(int i) throws Exception
{
    return null; // this would lead to a compiler error!
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案:在javadoc中明确地写它是我喜欢看到的(如http://stackoverflow.com/questions/61604中所述).但是,我很少从同事那里看到任何*完整的*javadoc.有时,我根本看不到任何javadoc,因为"代码本身就是一个文档"......唉 (3认同)

Apo*_*isp 8

您可以使用Option类型,这非常类似于具有零个或一个元素的列表.返回类型Option<Object>表示该方法可以返回一个Object,或者它可以返回一个特殊的类型值None.此类型可替代使用null和更好的类型检查.

例:

public Option<Integer> parseInt(String s) {
   try {
      return Option.some(Integer.parseInt(s));
   }
   catch (Exception e) {
      return Option.none();
   }
}
Run Code Online (Sandbox Code Playgroud)

如果你始终如一地使用它,你可以打开IDE无效警告,或者只使用grep,null如果你使用Option.none()你想要使用null文字的任何地方,就不应该出现在你的代码中.

Option标准的Scala,它Maybe在Haskell中调用.上面的链接是一个名为Functional Java的库,包含它.该版本实现了该Iterable接口,并具有monadic方法,可以让您很好地组合.例如,在以下情况下提供默认值0 None:

int x = optionalInt.orSome(0);
Run Code Online (Sandbox Code Playgroud)

你可以替换这个......

if (myString != null && !"".equals(myString))
Run Code Online (Sandbox Code Playgroud)

......有了这个,如果你有Option<String>......

for (String s : myOptionString)
Run Code Online (Sandbox Code Playgroud)

  • 6年后,Java 1.8现在有了一个非常有用的`Optional`类. (2认同)