On Java’s checked exceptions were a mistake (and here’s what I would like to do about it), Rolf Waldhoff introduced a “tunneling Exception through RuntimeException” concept:
I’ve grown increasingly fond of this approach, and think I’ll try to put something together in the Jakarta Commons sandbox for it.
I find checked exceptions painful for exactly the same reasons as Rod, but I don’t personally think they were a mistake. I like the “defensive programming” style, and I don’t mind being forced to be explicit about exceptions. The problem is with “middleware”, of course: how does a lower-level communicate checked exceptions to the higher-level without the “middleware” getting in the way.
Generic Java (JSR14) does introduce a way to mitigate this problem. It’s not a 100%
solution, but it has it’s place. Generics allows you to use an Exception as
a type parameter; so you might re-define the UnaryPredicate in Rod’s
example like this:
interface UnaryPredicate<T, E extends Exception> {
boolean test(T obj) throws E;
}
This says that UnaryPredicate has a method test()
that takes an argument of (some) type T and may throw an exception
of (some) type T.
The select() method then gets implemented this way:
public static <T, E extends Exception>
Collection<T> select(Iterator<T> iter,
UnaryPredicate<T,E> pred,
Collection<T> col)
throws E
{
while(iter.hasNext()) {
T obj = iter.next();
if(pred.test(obj)) {
col.add(obj);
}
}
return col;
}
Is that scary enough? Generics is cool, but make no mistake — Generics is complex. You would then use this method as follows:
class IsDirectory
implements UnaryPredicate<String, URISyntaxException>
{
public boolean test(String obj) throws URISyntaxException {
URI uri = new URI(obj);
File file = new File(uri);
return file.isDirectory();
}
}
...
Collection<String> allFiles = getListOfFiles();
Collection<String> directoriesOnly = new ArrayList<String>();
try {
CollectionAlgorithms.select(allFiles.iterator(),
new IsDirectory(),
directoriesOnly);
} catch (URISyntaxException e) {
// thrown when someObject isn't a valid URI
}
I think that’s a neat bit of syntax in use, but not in declaration. That is,
it’s nice to use select(), but the implementation of select()
is a bit of a mouthful.
