何时在构造函数中抛出异常?

3
public Neocortex(Region rootRegion, ConnectionInterface functor) {
this.rootRegion = rootRegion;
this.currentRegion = this.rootRegion;
this.functor = functor;
}

你好,上方是我一个类的构造函数。我的问题是,我是否应该在构造函数中添加空指针异常,或者这样做是否不必要?说实话,我并不明白何时应该在代码中添加异常。但是,在这种情况下,我应该使用哪个构造函数呢?

public Neocortex(Region rootRegion, ConnectionInterface functor) {
    if (rootRegion == null) {
    throw new NullPointerException("rootRegion cannot be null");
} else if (functor == null) {
        throw new NullPointerException("functor cannot be null");
    }
this.rootRegion = rootRegion;
this.currentRegion = this.rootRegion;
this.functor = functor;
}
4个回答

3
我会为那些构造函数的参数抛出一个IllegalArgumentException,如果这些参数被接受,将导致一些不好的结果(包括但不限于null参数)。也就是说,这将导致构造出一个没有意义的对象。
不要抛出NullPointerException,因为你还没有尝试在某个null上调用方法。
IllegalArgumentException javadocs中得知:

表示已传递非法或不合适的参数。

如果null是不合适的,则抛出IllegalArgumentException

3
不要抛出空指针异常,因为你还没有尝试在 null 上调用方法。对于任何不当使用 null 的情况,抛出 NullPointerException 都是完全有效的,而不仅仅是尝试取消引用它。请参见文档。实际上,文档中说你“应该”这样做。 - T.J. Crowder
1
@T.J.Crowder 确实,这可能是有效的,但在我看来,IllegalArgumentException 更清晰。我总是认为如果抛出 NullPointerException,那么就是取消引用了 null - rgettman
我倾向于区分期望在传递的对象上操作的方法(或构造函数)和期望在引用上操作而不考虑它指向什么的情况(例如,具有返回null的GetNextItem方法的队列当没有更多数据存在时可能不允许将空引用入队,但不会期望对传入的项进行解引用)。在后一种情况下抛出NPE将是意外的,但在前一种情况下则不是那么意外。 - supercat

3

嗯...这是一个品味问题。

如果类的先决条件是必须提供rootRegion,那么保护类的实现免受在所有地方进行空值检查的需要是有意义的。

所以回答“何时应在构造函数中抛出异常”的问题:我会在所有情况下都这样做,即当来自消费者的参数使您的实现处于无效状态时,委托问题(即抛出异常)。

如果您尝试一段时间担任消费者角色,并选择不进行空值检查,则他将拥有以下代码:

Neocortex n = new Neocortex(null,null);
n.doSomeething();

如果他到达第二行,而此处的实现抛出了NullPointerException,对于他来说,不清楚这是由于他提供的参数引起的。

1

如果null不是rootRegion等变量可以接受的值,则应从构造函数中抛出NullPointerException。参见NullPointerException documentation,其中介绍了JVM何时会抛出此异常,但也指出:

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

对于构造函数中不合法的参数,您可以使用IllegalArgumentException,但对于一个本应该不为null的参数,NullPointerException恰当地处理了这种情况。然而,IllegalArgumentException的优点在于它非常清楚地说明了问题所在。 :-)


0
在这种特定情况下,我会抛出一个IllegalArgumentException异常,对于你的类的用户来说,这比NullPointerException异常更有意义。
构造函数抛出异常并不是一种不好的做法。然而,你应该确保它们被很好地记录(特别是在运行时异常的情况下),并且对调用者有意义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接