views:

91

answers:

5

When you pass a callback in some form to another function, you often have to fullfil some interface to be able to pass such callback. That callback interface will often restrict you in what type of exceptions you can throw.

The most natural way for me would be that the called function would automatically rethrow (or ignore) the exceptions thrown by the callback. I.e. that it automatically inherits the list of exceptions it can throw from the callback. I.e. that the list of exceptions it can throw is generic.

Is something like possible already? If so, why isn't it used by Javas library yet?

If it is not possible yet, why not? It wouldn't have been complicated to include that in the language. And it would have made some things more clean (see above).


One example:

I just stumbled upon that Comparator.compare cannot throw an exception (see here for a related question) and Collections.sort (or other functions which use Comparator) also does not.

It would make much more sense to me if the exceptions which Comparator.compare can throw would be generic and Collections.sort would throw just the same. This would solve my problem here in a much more natural and clean way.

+5  A: 

I don't see any sensible reason why ordering objects should throw an exception. I'd just return -1 if ordering is "unspecified" so that it lands in top.

BalusC
The sorting itself not but your compare function for whatever reason.
Albert
The objects are already there. The information is already there. You just have to compare/arrange them so that it's clear which comes first. Why should that throw a checked exception? Under what condition specifically would you like to throw it?
BalusC
I agree. What on earth are you doing inside your comparator that can cause an exception?!
dty
I want to have `sort` throwing an exception if `compare` does.
Albert
That's not the point. Under what condition specifically would you like to have `compare()` throw a checked exception? Isn't this condition *after all* just caused by a developer's mistake?
BalusC
For the same reason you throw exceptions elsewhere in the code.
Albert
Checked exceptions indicate programmatic unrecoverable errors. I can't imagine of any programmatic unrecoverable problems when testing two readily available instances to determine which one should come before or after.
BalusC
Sure, I can somehow in any case define a well-defined order. But in my case, I am doing a very deep search on a graph structure and while doing that search, I can detect some inconsistence. I have defined an order for the nodes of the graph and I want to throw an exception when I am comparing two nodes which don't belong to the same graph. I don't want to include that case in my order. I am expecting that it doesn't happen and if it does, it should throw an exception.
Albert
That's thus a programmer's error. Those nodes shouldn't have been there in first place. In that case, throwing an unchecked exception is then perfectly valid. Unchecked exceptions indicate (programmatic recoverable) programmer's/enduser's/configuration errors. So, throw `RuntimeException` or a subclass of it. Maybe `IllegalStateException`.
BalusC
@BalusC: Ok, that makes sense and is a perfect answer now for [my other question](http://stackoverflow.com/questions/3832755/java-why-cant-i-throw-an-exception-in-comparator) but not really for this one here. I'll try to reformulate my question a bit. This question here is really not about ordering / `compare`.
Albert
It boils down to that it doesn't make sense to throw a checked exception out of comparing two objects which are supposed to be already present. That's all what the `compare()` method should be doing as per its contract.
BalusC
+4  A: 

I think throwing exception by a comparator breaks the single responsibility principle, the only job of a compare() method is to take two values and return a comparison result, while validness of objects should be checked earlier in a caller.

Vitalii Fedorenko
Does the single responsible principle holds also for interfaces (like `Comparator`)? Also, anyway, if the objects are valid itself but the custom compare function you code depends on some more complex conditions, who is responsible then? It seems to me that the `Comparator` implementation is the object which is responsible here.
Albert
Yes, it's the general principle that can be applied to anything. According to your second question, if you have for example orange and apple they are incomparable entities, so you should not try to compare them.
Vitalii Fedorenko
A: 

It doesn't make sense to complicate the API like this for every single implementation and every single piece of code that makes use of Comparators just so fringe cases that want to throw a checked exception can throw them rather than wrapping in a RuntimeException. I also think you're making a mistake in talking about subjective things like what's "natural" or "clean". I personally don't think it'd be clean at all to have to use <Foo, RuntimeException> as the type signature for 99.9% of all Comparators.

ColinD
The language could have support to interpret it automatically like this if you leave it away. Doesn't Java even do that in the upcoming version?
Albert
Also, doesn't it seem like a workaround for you to *wrap* your actual exception in a `RuntimeException`?
Albert
@Albert: JDK8 might have some kind of support for exception transparency, though I'm not sure that `Comparator` would be able to make use of it. Additionally, the form that this exception transparency will take is far from decided and quite a few people don't like the current version. But yes, with good language support this sort of thing could work.
ColinD
A: 
Skip Head
Maybe for `Comparator` but this question is not about that (that is only one example). Also, what you described is not possible. The point where I see that something wrong is only while comparing them, not before.
Albert
A: 

Noone really has given an answer yet (most answers were only specific about my example, why it might not be a good thing in that case), so here I try to answer it myself:

No, it is not possible yet.

The most probably reason why it is not there is to keep things more simpel. Otherwise, no specific reason.

Albert