在类构造函数中使用异常处理代码是否合法,还是应该避免?应该避免在构造函数中生成异常代码吗?
答案 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(...);
}