11

在 Java 代码中进行空值检查时,如果你为空值抛出 IllegalArgumentExceptions,你使用什么样的消息模板?

我们倾向于使用这样的东西

public User getUser(String username){
   if (username == null){
     throw new IllegalArgumentException("username is null");   
   }
   // ...
}

什么更好:“为空”或“为空”,为什么?

对我来说,“is null”感觉更自然。

4

4 回答 4

15

由于Exception由于前置条件检查失败而引发了,我认为您应该说明违反的要求,而不是简单地陈述一个事实。

也就是说,与其说,不如"username is null""username should not be null"


关于使用库进行前置条件检查

作为提示,您可以使用许多旨在促进前提条件检查的库之一。Guava 中的许多代码使用com.google.common.base.Preconditions

在您自己的方法开始时调用简单的静态方法以验证正确的参数和状态。这允许诸如

 if (count <= 0) {
   throw new IllegalArgumentException("must be positive: " + count);
 }

换成更紧凑的

 checkArgument(count > 0, "must be positive: %s", count);

这里更直接相关的是它具有checkNotNull,它允许您简单地编写:

  checkNotNull(username, "username should not be null");

请注意上面的代码读起来是多么自然,详细的消息明确说明了违反的要求。

陈述事实的替代方案更尴尬:

 // Awkward!
 checkArgument(count > 0, "is negative or zero: %s", count);
 checkNotNull(username, "username is null");

此外,这也可能不太有用,因为客户可能已经意识到这一事实,并且异常并不能帮助他们弄清楚实际需求是什么。


IllegalArgumentException_NullPointerException

虽然您的原始代码会抛出IllegalArgumentException参数null,但 Guava 会Preconditions.checkNotNull抛出NullPointerException

这符合 API 设置的指南:

NullPointerException: 应用程序应该抛出这个类的实例来指示null对象的其他非法使用。

此外,这里引用Effective Java 2nd Edition:第 60 条:支持使用标准异常

可以说,所有错误的方法调用都归结为非法参数或非法状态,但其他异常通常用于某些类型的非法参数和状态。如果调用者传入null了一些禁止 null 值的参数,则约定将NullPointerException其抛出而不是IllegalArgumentException.

于 2010-06-11T11:34:43.217 回答
5

是 null,因为参数仍然是 null ..

但是,为什么不直接抛出 NullPointerException 而没有消息呢?

于 2010-06-11T11:32:55.120 回答
0

我建议说

  if (userName == null) {
     throw new IllegalArgumentException("username == null");
   }

因为这太致命了,程序员无论如何都必须查看它。在异常消息中引用有问题的代码片段是我能想象到的最简洁的事情。

于 2010-06-11T12:32:55.800 回答
0

我倾向于这样写:

public User getUser(String username) {
   if (username.length() == 0) {
       throw new IllegalArgumentException("username is empty");   
   }
   // ...
}

这会用一块石头杀死两只鸟。首先,它检测到用户名是空字符串的情况,我假设这是一个错误(为了论证)。其次,如果参数null试图分派length调用将给出一个NullPointerException.

作为记录,为意外抛出的预期异常nullNullPointerException. 如果您不使用它的主要原因是 NPE 通常没有消息,请将其编码如下:

public User getUser(String username){
   if (username == null){
       throw new NullPointerException("username is null");   
   }
   if (username.length() == 0) {
       throw new IllegalArgumentException("username is empty");   
   }
   // ...
}

为什么在这里使用 NPE?因为 NPE 几乎总是表明与其他类型的参数验证错误不同的问题;例如,尚未初始化的字段或数组单元格或未正确处理的“可选”值。

最后到问题:

什么更好:"is null""was null",为什么?

这是一个见仁见智的问题,但我会写"is null"

  • 因为该消息正在报告引发异常时的状态。
  • 因为这样做是常规的。
于 2010-06-11T13:35:23.063 回答