Given the code:
public static int sum(String a, String b) /* throws? WHAT? */ {
int x = Integer.parseInt(a); // throws NumberFormatException
int y = Integer.parseInt(b); // throws NumberFormatException
return x + y;
}
Could you tell if it’s good Java or not? What I’m talking about is, NumberFormatException is an unchecked exception. You don’t have to specify it as part of sum() signature. Moreover, as far as I understand, the idea of unchecked exceptions is just to signal that program’s implementation is incorrect, and even more, catching unchecked exceptions is a bad idea, since it’s like fixing bad program at runtime.
Would somebody please clarify whether:
- I should specify
NumberFormatExceptionas a part of method’s signature. - I should define my own checked exception (
BadDataException), handleNumberFormatExceptioninside the method and re-throw it asBadDataException. - I should define my own checked exception (
BadDataException), validate both strings some way like regular expressions and throw myBadDataExceptionif it doesn’t match. - Your idea?
Update:
Imagine, it’s not an open-source framework, that you should use for some reason. You look at method’s signature and think – "OK, it never throws". Then, some day, you got an exception. Is it normal?
Update 2:
There are some comments saying my sum(String, String) is a bad design. I do absolutely agree, but for those who believe that original problem would just never appear if we had good design, here’s an extra question:
The problem definition is like this: you have a data source where numbers are stored as Strings. This source may be XML file, web page, desktop window with 2 edit boxes, whatever.
Your goal is to implement the logic that takes these 2 Strings, converts them to ints and displays message box saying "the sum is xxx".
No matter what’s the approach you use to design/implement this, you’ll have these 2 points of inner functionality:
- A place where you convert
Stringtoint - A place where you add 2
ints
The primary question of my original post is:
Integer.parseInt() expects correct string to be passed. Whenever you pass a bad string, it means that your program is incorrect (not "your user is an idiot"). You need to implement the piece of code where on one hand you have Integer.parseInt() with MUST semantics and on the other hand you need to be OK with the cases when input is incorrect – SHOULD semantics.
So, briefly: how do I implement SHOULD semantics if I only have MUST libraries.
This is a good question. I wish more people would think about such things.
IMHO, throwing unchecked exceptions is acceptable if you’ve been passed rubbish parameters.
Generally speaking, you shouldn’t throw
BadDataExceptionbecause you shouldn’t use Exceptions to control program flow. Exceptions are for the exceptional. Callers to your method can know before they call it if their strings are numbers or not, so passing rubbish in is avoidable and therefore can be considered a programming error, which means it’s OK to throw unchecked exceptions.Regarding declaring
throws NumberFormatException– this is not that useful, because few will notice due to NumberFormatException being unchecked. However, IDE’s can make use of it and offer to wrap intry/catchcorrectly. A good option is to use javadoc as well, eg:EDITED:
The commenters have made valid points. You need to consider how this will be used and the overall design of your app.
If the method will be used all over the place, and it’s important that all callers handle problems, the declare the method as throwing a checked exception (forcing callers to deal with problems), but cluttering the code with
try/catchblocks.If on the other hand we are using this method with data we trust, then declare it as above, because it is not expected to ever explode and you avoid the code clutter of essentially unnecessary
try/catchblocks.