将异常处理放在构造函数中是一种好习惯吗?

时间:2010-02-03 19:17:06

标签: exception-handling constructor

在类构造函数中使用异常处理代码是否合法,还是应该避免?应该避免在构造函数中生成异常代码吗?

7 个答案:

答案 0 :(得分:9)

是的,这是完全合理的。你怎么会有这样的情况:

class List {
    public List(int length) {
        if(length < 0) {
            throw new ArgumentOutOfRangeException(
                "length",
                "length can not be negative"
            );
        }
        // okay, go!
    }
}

长度为负的List绝对是例外。你不能让这个回到调用者那里让他们认为构建是成功的。有什么替代方案,CheckIfConstructionSucceeded实例成员函数?令人讨厌。

或者

class FileParser {
    public FileParser(string path) {
        if(!File.Exists(path)) {
            throw new FileNotFoundException(path);
        }
        // okay, go!
    }
}

同样,这是一次投掷,其他任何事情都不可接受。

答案 1 :(得分:4)

假设你正在谈论它是C ++,提出异常实际上是在构造函数中发出错误信号的唯一方法 - 所以这绝对不应该避免(*)

至于处理构造函数内部的异常,这也是完全有效的,因为你实际上可以处理异常。只需遵循这里的通用规则:在可以处理它们的级别捕获异常/对它们执行有意义的操作。

  

(*)只要你不是邪教   这避免了C ++中的异常

答案 2 :(得分:3)

在C ++中,ctors最适合抛出异常。 FAQ:17.2

答案 3 :(得分:3)

我认为在构造函数中抛出异常以停止创建对象是有效的。

答案 4 :(得分:3)

在任何可能抛出异常的地方,“最佳实践”是处理它,构造函数或其他方式。

它确实为构造函数添加了另一层复杂性,因为即使发生错误,您也必须确保所有内容都已正确初始化,但它比有错误的代码更好:)

答案 5 :(得分:2)

一般来说,我认为应该尽可能避免在构造函数中生成异常代码。这是非常特定于语言的 - 但是在某些语言中,抛出异常的构造函数会导致不可恢复的问题,但在其他一些语言中,它很好。

就个人而言,我尝试让我的构造函数尽可能少地将对象置于有效状态。一般来说,这意味着它们不会抛出,除非它是一个真正的例外情况(我无论如何都无法处理)。

答案 6 :(得分:0)

当然,尽早失败!在构造函数内部,输入参数的一些验证可能会出错,因此失败是绝对值得的,而不是继续使用不一致的构建数据。


Constructor(Param param){
  if(param == null)
    throw new IllegalArgumentException(...);
}