4 ms·
The checked exception didn't break encapsulation here, you did. You have alot more than two options, and the two you listed aren't very good ones. If foo call
by efsavage 17y ago
The checked exception didn't break encapsulation here, you did. You have alot more than two options, and the two you listed aren't very good ones.
If foo calls bar, something might go wrong, and foo should take some kind of action. If bar can't complete because of an IOException, it should throw it (or wrap it and throw the wrapper). Foo now knows that bar may not complete successfully, and can do what makes sense there (throw it's own exception, retry, etc). If foo can't complete because bar didn't complete, it should tell it's caller. If it matters that the reason Foo couldn't complete was an IOException, throw it, otherwise throw a more meaningful exception.
- akeefer 17y agoLet me try to phrase the argument more clearly: if you want to pass on a checked exception via redeclaration in the "throws" clause, you've broken encapsulation because a change to the lower layer implies changes all the way up the stack. If bar() was originally calling readDatabase() that threw a SQLException, and I change it to call readFile() that throws an IOException, if I'm passing that exception up the stack I have to change bar's signature purely due to an implementation change, and so on up the stack. So a change at the lower layer has now forced me to make changes all the way through my application stack. Henceforth, encapsulation is broken by what should just be an implementation change. The only way to avoid that break of encapsulation is to catch the exception immediately in bar(), and then do something with it: either handle it, or rethrow it as something else, either a runtime exception or as a different checked exception. But that also isn't really ideal; in my experience, about 98% of the time even checked exceptions are throw-up-your-hands sort of programmer errors that you want to bounce a fair way up the stack to some more central error-handling location, or to kill the high-level operation being attempted. In other words . . . you generally just want to treat them exactly like runtime exceptions. So while the theory of type-safety around checked exceptions is nice and all, in practice if you actually use them as part of type signatures they massively couple all the layers of your application, and I find them much more annoying than useful.