Is it good practice to put exception handling in a constructor?
Is it legitimate to have exception handling code in a class constructor, or should it be avoided? Should one 开发者_C百科avoid having exception-generating code in a constructor?
Yes, it's perfectly reasonable. How else would you have a circumstance like this:
class List {
public List(int length) {
if(length < 0) {
throw new ArgumentOutOfRangeException(
"length",
"length can not be negative"
);
}
// okay, go!
}
}
A List
with negative length is most certainly exceptional. You can not let this get back to the caller and have them think that construction was successful. What's the alternative, a CheckIfConstructionSucceeded
instance member function? Yucky.
Or what about
class FileParser {
public FileParser(string path) {
if(!File.Exists(path)) {
throw new FileNotFoundException(path);
}
// okay, go!
}
}
Again, this is a throw and nothing else is acceptable.
Assuming it's C++ you're talking about, raising exceptions is actually the only way to signal errors in a constructor - so this definitely shouldn't be avoided (*)
As to handling exceptions inside constructors, this is also perfectly valid, granted that you actually can handle the exception. Just follow the common rule here: catch exceptions at the level where you can handle them / do something meaningful about them.
(*) As long as you're not of the cult that avoids exceptions in C++
In C++, ctors are best placed to throw exceptions back up. FAQ:17.2
I believe it's valid to throw an exception in a constructor to stop the creation of the object.
In general, I think that exception-generating code should be avoided whenever possible in constructors. This is very language specific, however - in some languages, constructors throwing an exception cause unrecoverable issues, but in some other languages, it's fine.
Personally, I try to make my constructors do as little as possible to put the object into a valid state. This would, in general, mean that they are not going to throw, unless it's a truly exception case (which I can't really handle anyways).
Anywhere there is the possibility of an exception being thrown, the "best practice" is to handle it, constructor or otherwise.
It does add another layer of complexity to the constructor, since you have to ensure everything is initialized correctly even if an error does occur, but it's better than having buggy code :)
Sure, fail as early as you can! Inside constructors some validation of input params can go wrong, so it is defintely worth to fail, instead of proceeding with inconsistent built data.
Constructor(Param param){
if(param == null)
throw new IllegalArgumentException(...);
}
精彩评论