6

I've been reading about unchecked versus checked questions, none of the online resources have been truly clear about the difference and when to use both.

From what I understand, both of them get thrown at runtime, both of them represent program states that are outside the expected bounds of the logic, but checked exceptions must be explicitly caught while unchecked ones do not.

My question is, suppose for argument's sake I have a method that divides two numbers

double divide(double numerator, double denominator)
{    return numerator / denominator;    }

and a method that requires divison somewhere

void foo()
{    double a = divide(b, c);    }

Who is responsible for checking the case of the denominator being zero, and should an exception be checked or unchecked (ignoring Java's built in divison checks)?

So, would the divide method be declared as is or as

double divide(double numerator, double denominator) throws DivideByZeroException
{
    if(denominator == 0) throw DivideByZeroException
    else ...
}

void foo()
{
    try{
        double a = divide(b, c);
    }
    catch(DivideByZeroException e)
    {}
}

or without a checked exception, as is:

double divide(double numerator, double denominator)
{
    if(denominator == 0) throw DivideByZeroException
    else ...
}

void foo()
{
    if(c != 0)
       double a = divide(b, c);
}

and allow foo to make the divide by zero check?

This problem originally arose in a mathematical program I wrote in which users entered numbers and logic classes performed calculations. I was never sure whether the GUI should check immediately for improper values, or whether the internal logic should catch them during calculation and throw exceptions.

donnyton
  • 5,668
  • 9
  • 39
  • 59
  • I can elaborate on the topic but the whole example is entirely wrong: because? Only integer division by zero results in an exception. Floating point one (double incl) results either in some infinity (neg/pos) or a "simple" NaN (in case of 0/0) – bestsss Feb 21 '11 at 20:35
  • You're right, and I said to ignore java's default division checks and assume for argument's sake that we want to treat division by zero as an error (which it happens to be in my original program). – donnyton Feb 22 '11 at 02:19
  • that's not related to the exception handling but *do not* checkd double==0, it may not work properly for values close but not equal (==) zero. Floating point division by zero is not an error by design. Most of the code should be able to properly handle infinity/nan and deal with such cases. So in your case you need smth like `if (Math.abs(denominator) – bestsss Feb 23 '11 at 14:22

6 Answers6

8

Interesting topic indeed!

After reading and trying lots of way to deal with errors in general and exceptions specifically I learned to differ between programmer errors and a expected errors.

Programmer errors should never be caught, but rather crash (!) early and hard. A programmer error is due to a logical fault, and the root cause should be fixed.

Expected errors should always be caught. Also when a expected error is caught a message must be displayed for the user. This has an important implication - If a expected error should not display an error, it's better to check whether the method will throw instead of letting it throw.

So applied to your example I would think "How should this look to the user?"

  1. If a error-message should be displayed (in the browser output, console, messagebox) I would throw an exception and catch it as close to the UI as possible and output the error-message.
  2. If no error message should be displayed I would check the input and not throw.

On a sidenote: I never throw DivideByZeroException nor NullPointerException - I let the JVM throw those for me. In this case you could brew your own exception-class or use a suitable built-in checked exception.

vidstige
  • 11,161
  • 7
  • 58
  • 95
  • 1
    +1: Don't catch RuntimeExceptions but fix the underlying programming error (in this case not checking if the denominator is null). The only exception I can think of is parsing user input where we're pretty much limited by Java. – Voo Feb 21 '11 at 21:35
  • @Voo, The unchecked exceptions do not define neither programmer errors, nor expected ones. There are bugs/errors in java and many 3rd party libraries and while I may opt to patch some (bootstrap path, fixing bugs in the source, etc), catching exception is a necessary evil. If anyone has written any container alike, catching RuntimeException is the norm. – bestsss Feb 22 '11 at 06:10
  • @bestsss sometimes you cannot fix the source of exceptions. Some libraries throw runtime exceptions that is impossible to check beforehand if they will be thrown, etc. This does not mean you should add to this mess. Instead handle it the best way possible. For example catch the ugly exception thrown by library as soon as possible and rethrow, etc. – vidstige Feb 22 '11 at 08:37
1

My favorite discussion on the difference in philosophy between checked and unchecked exceptions in Java:

http://www.javapractices.com/topic/TopicAction.do?Id=129

Mike Yockey
  • 4,539
  • 20
  • 41
  • 1
    I've read that page and understand the general idea of it but not the specific examples. In particular, why does the second example on that page choose to leave the exception unchecked? Is it because the programmer is guaranteed that the checkForContent(String) method will never interact with outside/user inputs? And if so, why is it guaranteed this and the Resto() constructor not guaranteed it? – donnyton Feb 21 '11 at 20:40
  • 2
    As the example notes point out, the object has no apparent control over the content passed to it. It's a model object and will thus contain data direct from the user in a non-validated state, which must be assumed unsanitary. The second example is a utility class used only internally by the application. Since data passed to it is under the full control of the application, it shouldn't generate any checked exceptions. More specifically, there should be zero cases not handled by application logic. If exceptions arise, it's a result of an error in the program, and shouldn't be handled. – Mike Yockey Feb 21 '11 at 20:52
  • So, if I am understanding it right, what the exception actually represents is less important than how closely it interacts with the user. That is, a checked-exception method that gets moved from user input into internal logic may in fact benefit from becoming unchecked? – donnyton Feb 22 '11 at 02:27
1

Java exceptions are checked only by the compiler, however java designers decided to split them into multiple categories, basically involving the superclass being extended

  • java.lang.Exception - known as checked exceptions
  • java.lang.RuntimeException known as UNchecked exceptions - as bonus java.land.RuntimeException extends java.lang.Exception (to ease the handling in catch blocks, and not only)
  • java.lang.Error - errors, also unchecked and rarely needed to be handled by user-space code, but knowing them and their variance is a major plus. They include (most famous): linkage error, stackoverflow, out of memory, assertion errors
  • java.lang.Throwable - Checked! and the mother of all exceptions, few need to directly subclass it, but some does for unknown reasons

So it's about need to declare the exceptions and taking care of proper propagation (on compile only level), unchecked ones are auto-propagated and the developer is not expected to provide handling of unless needed.

Checked ones are generally expected to happen and require extra verbosity in the java, already fluffy code.

Worst practices include: catch (Throwable t){}, for many a reason, usually errors shall not be handled unless necessary and most errors usually spell the thread death either ways.

bestsss
  • 10,864
  • 3
  • 49
  • 62
1

Assume that a checked exception is thrown as a result of a mathematical operation. E.g division (as per your post).
This would mean that every integer division should appear in a try block!
Actually division can throw an ArithmeticException which is unchecked exception so there is no need to catch it.
Actually you should not catch it, since it is an exceptional condition that occured and usually can only be solved by code correction.
In your case your code should have done something prior to actually divide by zero.
If you have reached the step where you allow to actually do the division by zero then there is nothing you can do. The program is erroneous and it is best to be fixed than try to somehow disguise it by throwing/catching an exception

Cratylus
  • 49,824
  • 60
  • 195
  • 327
0

Short answer as some pros and cons have been named: It is a matter of personal or organisational style. None is functionally better than the other. You (or your project) will have to make your own decisions about whether to use checked or unchecked exceptions, or both.

Oracle's Java Tutorial advices you to use checked exceptions for all errors the application can recover from, and unchecked exceptions for the errors the application cannot recover from. But from my experience most applications may recover from most (maybe not during startup) exceptions. The action that failed will be aborted but the application stays alive.

I would rather only use either checked exceptions or unchecked exceptions. Mixing may result in confusion and inconsistent use. Be pragmatic. Do what makes sense in your situation.

Chris
  • 7,308
  • 1
  • 25
  • 37
0

Never explicitly throw RuntimeExceptions. If you ever think you need to then just let the runtime do it rather than using throw.

CurtainDog
  • 3,106
  • 19
  • 17