空检查错误消息为“为空”或“为空”
在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
。