Re: One phrase says it all.
As I was writing that phrase about more information being good, regardless of it being wrong kind of struck me as a really poor way of explaining things. On the surface, I would completely agree with you.
It makes some sense that, given an interface (with defined checked exceptions) with a particular implementation not throwing said exceptions, that the interface is considered "wrong" because an implementation doesn't actually implement it (that is, it doesn't have the possibility of throwing an exception, so it could be said that the interface isn't truly implemented properly....it's "wrong").
However, that's not how I looked at it (though that appears to be how I said it, which is obviously my fault). The way I looked at it was that the interface defines a particular set of signatures (for our purposes, one is enough). For that particular signature, it defines three basic things: the return type, the parameters, and a checked exception (I know, there are other things in there, such as the ordering and types of parameters, etc...just trying to keep things simple). The checked exception means (as I look at it) that the method *may* throw an exception of that type. That means that it may not. In fact, I *hope* that it doesn't, but I code such that it might.
Because I trust the signature (the compiler says I can), I assume that it's possible. The checked exception gives me additional information in that it's a *hint* that a particular exception *may* (and *can*) be thrown. It doesn't state that it *must* or that it *will* under any given circumstances. In that case, it's additional information that isn't necessarily *wrong* if a particular implementation doesn't actually throw the said exception. It comes back to perception, I guess.
If we change the example so that it was an unchecked exception, instead, would that change anything? First off, I would *hope* and assume that the interface was well enough documented that it would indicate that an unchecked exception might be thrown under certain situations (something like: this method may throw this exception....). If not, then I would not have a lot of trust in that interface as I'd probably get exceptions thrown and not know that I was to catch them (this isn't a question of *where*, but the need to know that it can so that I can make the decision as to where).
Given that it's well documented, what about an implementation of that interface that didn't throw the exception? Depending upon how I use that interface, I may not know that a particular implementation doesn't throw the exception? Why? Because the construction of the implementation may be hidden from me, so I may not even know what class I'm actually using (that's the whole point of using an interface, after all). So, I would handle the situation identically, regardless of whether there was a checked or unchecked exception (granted that there may be slight differences in the syntax, since I have more flexibility as to where I deal with the unchecked exception, but I also have better inherent documentation with the checked one...it's a trade-off, to a certain extent).
As for a good example of a checked exception...
Since most of my current experience is with web-based apps, I'll use a fairly simple example: a Struts-based web app.
I create a business object layer that handles the business logic (and, somewhere in there, persistence). That layer defines some interfaces and concrete classes that the presentation layer interfaces with. Where appropriate, the business layer throws a standard application exception (with possibly a couple sub-classes if necessary). In the presentation layer (say, the struts action class), calls are made into the business layer. Since I, as the business layer writer, provide a single exception layer to the presentation layer, it can easily have code that does something like this:
try
{
...get data from user or whatever.
callBusinessLayerA(...);
callBusinessLayerB(...);
...use data from business layer to setup view or whatever.
}
catch ( ApplicationException e )
{
..set up error messages to display error from business layer...
}
Obviously, I'm leaving out lots of details, but the idea is that the presentation layer only deals with one (or only a very small number) application layer.
Of course, this can just as easily be done using unchecked exceptions. The difference is one of safety. As the writer of the business layer, I'm forcing the presentation layer developer to deal with my exceptions. If he merely ignores them (nothing in the catch), then hopefully, that'll get caught in testing or code review. In fact, it's fairly easy to write up a tool to automatically find those kinds of bugs (there are probably tools out there that do it, in fact).
I realize that it's a fairly simple example, but the idea of layering the exceptions simplifies things considerably. When dealing with junior to mid-level developers, I like the additional safety (try working at places like EDS or Accenture where the developers are not trained or taught...having extra checks like this are really helpful).
Dan