我对Java的最佳实践有疑问。我正在写一个类,它依赖于构造中的一个对象。实际上,如果在构造中传入的对象为null,则大多数功能都没有意义。我认为最好在对象构造中将null作为参数传递的情况下抛出异常,但我不知道在这种情况下最合适的异常是什么。我应该抛出NullPointer,IllegalArgument,Instatiation,甚至是初始化异常。
我已经看到这些都在整个Java源代码库中使用,我似乎无法区分为什么在某些情况下使用NullPointer而在其他情况下使用IllegalArgument。我个人会想到如果在构造中传递了一个错误的参数,就会发生一些初始化错误。
答案 0 :(得分:5)
首先,你应该绝对抛出异常。这只是正确的事情。
至于你是否应该抛出IllegalArgumentException
或NullPointerException
- Josh Bloch在Effective Java中谈到这一点,并且通常得出结论:NullPointerException
是一个合理的选择。我不完全确定我同意(我可能会选择IllegalArgumentException
),但最终它不太重要:你不应该直接捕获这些异常中的任何一个,并且堆栈跟踪将显示哪里有问题无论如何。
(遗憾的是,Java没有相当于.NET的ArgumentNullException
,这意味着它的确如此。)
我个人非常喜欢Guava的Preconditions
课程:
public class Foo {
private final Bar bar;
public Foo(Bar bar) {
this.bar = Preconditions.checkNotNull(bar);
}
}
(有时与checkNotNull
的静态导入一起使用。)
答案 1 :(得分:4)
IllegalArgument向使用该代码的开发人员说明问题是什么,以及如何解决问题。它还清楚地表明,如果没有该对象,该方法就无法工作。
NullPointer意味着他们必须考虑一下问题是什么(不多)并且可能意味着代码更清晰,但就像我上面所说的那样。从文档的角度来看,您的代码是否可以使用null值,并不是很清楚。
答案 2 :(得分:1)
NullPointerException
时,会使用 null
。当尝试在null
对象上调用方法时,这尤其相关。这是最常见的用途。但是,您的案件也可以保证。
IllegalArgumentException
。在我的视图中 ,在您的情况下更合适。您期望一个有效的对象,但您收到null
作为参数。这个参数值是无效的 - 所以我会抛出IllegalArgumentException
并在异常的消息中指明错误,例如:
public MyClass(InputObject obj) {
if(obj == null) {
throw new IllegalArgumentException("null passed to MyClass constructor");
}
...
}
答案 3 :(得分:1)
如果您认为平台异常没有为客户提供正确数量的信息来理解和解决问题,那么您可以创建自己的例外,这在这方面更合适,比如.NET的ArgumentNullException
;它会告诉客户问题是什么和如何解决问题。