空检查错误消息为“为空”或“为空”

在Java代码中执行空检查,并且为空值抛出IllegalArgumentExceptions时,您使用什么类型的消息模板?

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

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

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

对我来说,“无效”感觉更自然。

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

也就是说,不要说"username is null" ,而是说"username should not be null"


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

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

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

  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"); 

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


On IllegalArgumentException vs NullPointerException

当您的原始代码在null参数上抛出IllegalArgumentException时,Guava的Preconditions.checkNotNull会抛出NullPointerException

这符合API设定的准则:

NullPointerException :应用程序应抛出此类的实例以指示null对象的其他非法使用。

另外,这里引用了Effective Java 2nd Edition:第60项:赞成使用标准exception

可以说,所有错误的方法调用都归结为非法论证或非法状态,但其他例外标准地用于某些非法论证和状态。 如果调用者在某些禁止空值的参数中传递null ,则约定表示抛出NullPointerException而不是IllegalArgumentException

为null ,因为参数仍为null。

但是,为什么不简单地抛出没有消息的NullPointerException?

我建议说

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

因为这是致命的,程序员无论如何都必须看它。 在exception消息中引用违规代码片段是我能想象到的最简洁的事情。

我倾向于写这个:

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

这可以一石二鸟。 首先,它检测用户名是空字符串的情况,这(为了参数)我假设是一个错误。 其次,如果参数为null尝试调度length调用将给我们NullPointerException