Search code examples
javaexception

Java custom exception handling. Which class to extend?


I am taking a Java course. So I am just learning Java. The textbook says to either extend the Exception class or extend the RuntimeException class for a custom exception. I understand RuntimeException is a subclass of Exception.

I have a homework assignment to implement the bin2Dec method to throw a custom exception if the string is not a binary string.

I found the exercise worked out by somebody and was studying their solution. However, I see that they extended the NumberFormatException class which of course is a child of IllegalArgumentException which is a child of RuntimeException.

This led me to wonder why they decided to use NumberFormatException? I assume I can work out a solution simply using Exception or RuntimeException. Especially since that is all that is covered in the text.

I tried searching the web to find answers to this question but all I found was several places stating basically what the book says (extend Exception or RuntimeException) and explaining (as the book does) when to use one vs the other.

All I was able to find was several articles saying that you "can" use a more appropriate subclass like NumberFormatException but no explanation of how a person would come to that conclusion when setting out to make a custom exception. I found one article saying extending NumberFormatException is almost always a bad idea and explained several reasons why but then it said IllegalArgumentException would likely be more appropriate. This leaves me wondering the same question... What would lead me to decide to use IllegalArgumentException instead of Exception or RuntimeException.


Solution

  • This led me to wonder why they decided to use "NumberFormatException"?

    NumberFormatException is a very clear Exception; it says that the String (or other object) that the program tried to convert to a number wasn't in a format that the Method could read. With this information, the programmer can go to the Javadocs to learn more about their misunderstanding of what the input to the method that generated this exception should look like. So in your case using NumberFormatException or subclassing it and using that subclass seems like it would be very appropriate for a function that converts a binary number to a decimal number.

    In terms of the bigger picture:

    1. subclassing from RuntimeException is often the best way to go (IMO). I like the "fast fail" paradigm: Fail, and describe the failure reason. The client user has the option of running again and fixing the input... or just not. I prefer not to loop and ask the user for input repeatedly until its valid, and I think this can be annoying. A good non-RuntimeException example is IOException and its subclass SocketException. Sockets (and SocketExceptions) are a regular part of cross-computer communication, and a SocketException on a port that is listening for input lets the programmer know that the Socket has been closed, and releases the Socket and the Thread waiting on it.
    2. FYI There is a 3rd kind of Throwable, which is Error. When you have time you should read about what makes an Error an Error.
    3. Java and the Java console in particular make input validation more complicated than it can otherwise be. The state of the art on this right now (IMO) is HTML 5, where you can specify both the type of an INPUT (like number, url, etc) and/or a Regular Expression pattern that the input must follow. Using these, the web browser will stop the user from submitting a form if the input is not valid.

    --Edit--

    Hinza Zidek below has a good point that even if you validate a submission using HTML5, you still need to check the validation on the server(Java) side