Joshua Bloch in his Effective Java writes :
"Use the Javadoc @throws tag to document each unchecked exception that a method can throw, but do not use the throws keyword to include unchecked exceptions in the method declaration. "
Well that sounds reasonable indeed, but how to find out, what unchecked exception can my method throw?
Let's think of a following class :
public class FooClass {
private MyClass[] myClass;
/**
* Creates new FooClass
*/
public FooClass() {
// code omitted
// do something with myClass
}
/**
* Performs foo operation.<br />
* Whatever is calculated.
* @param index Index of a desired element
* @throws HorribleException When something horrible happens during computation
*/
public void foo(int index) {
try {
myClass[index].doComputation();
} catch (MyComputationException e) {
System.out.println("Something horrible happened during computation");
throw new HorribleException(e);
}
}
}
Now, I documented HorribleException, but it is quite obvious, that foo method can also throw unchecked java.lang.ArrayIndexOutOfBoundsException. The more complex the code gets, it's harder to think of all unchecked exceptions that method can throw. My IDE doesn't help me much there and nor does any tool. Since I don't know any tool for this ...
How do you deal with this kind of situation?
We have a written checkstyle extension that run on our test server. In your sample it would test if HorribleException was documented.
The ArrayIndexOutOfBoundsException will detect with a code review. In your sample code our goals required to throw a InvalidArgumentException instead a ArrayIndexOutOfBoundsException. The documentation of it will be find from test server.
The ArrayIndexOutOfBoundsException can be a warning in FindBugs. But I am not sure.
Document only what you're throwing yourself.
In this case, I'd go for a index bounds check and throw my own exception:
throw IllegalArgumentException("Index must be smaller than " +myClass.length + ", but is: " + index)
and then document the IllegalArgumentException in the JavaDoc.Only document those which you're explicitly throwing yourself or are passing through from another method. The remnant is to be accounted as bugs which are to be fixed by good unit testing and writing solid code.
In this particular case, I'd account
ArrayIndexOutOfBoundsException
as a bug in your code and I'd fix the code accordingly that it never throws it. I.e. add a check if the array index is in range and handle accordingly by either throwing an exception -which you document- or taking an alternative path.Where you see a problem, I see a very good reason to keep your code simple ;-)
In your exemple, I'd suggest to document the
ArrayIndexOutOfBoundsException
. Just because that's something someone can have when giving a bad parameter to you method, and it should be written somewhere : "If you given an invalid array index, you'll get anArrayIndexOutOfBoundsException
. For example, theString#charAt()
method documents it can throw anIndexOutOfBoundException
if the index isn't valid.In general, you shouldn't document al the exceptions that can arise. You can't predict them all, and you're very likely to forget one. So, document the obvious ones, the one you though of. Try to list the most exceptions as possible, but don't spend to much time on it. After all, if you forget one that should be documented, you can improve your documentation later.
The quote you posted, is just something you have to keep in mind if you want to be the ideal programmer. Programming is not thinking "what can go wrong", but is think how to do something the best way and program it. If it is a personal project, just write what the method does.
However, there are three possible solutions:
if (obj == null) { throw new NullPointerException(); }
).