Java unchecked/checked exception clarification - java

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.

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?"
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.
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.

My favorite discussion on the difference in philosophy between checked and unchecked exceptions in Java:
http://www.javapractices.com/topic/TopicAction.do?Id=129

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

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.

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.

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

Related

Java API and checked/unchecked exceptions confusion

The question about checked and unchecked exceptions was raised here and on other websites million times, but I'm still confused with so different answers.
In many answers and articles we can read general statements like:
Unchecked runtime exceptions represent conditions that, generally
speaking, reflect errors in your program's logic and cannot be
reasonably recovered from at run time.
and for checked exceptions
represent invalid conditions in areas outside the immediate control of
the program (invalid user input, database problems, network outages,
absent files)
both quotes are from http://www.javapractices.com/topic/TopicAction.do?Id=129 and are cited many times.
We can read similar statements on oracle website:
Runtime exceptions represent problems that are the result of a
programming problem, and as such, the API client code cannot
reasonably be expected to recover from them or to handle them in any
way
http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
Lets take simple example with reading Number with Scanner:
Scanner sc = new Scanner(System.in);
int userInput = sc.nextInt();
System.out.println(userInput);
nextInt() throws InputMismatchException when I type i.e. "asdf" instead of int. InputMismatchException is RuntimeException but according to statements above this is the first example of checked exceptions "invalid user input".
When I look at checked exceptions I am even more confused. For example NPE vs FileNotFoundException - both can be prevented by simple if-else, so why first one is unchecked and second is checked?
Oracle website has bottom line guideline:
If a client can reasonably be expected to recover from an exception,
make it a checked exception. If a client cannot do anything to recover
from the exception, make it an unchecked exception.
So according to that I can recover from FileNotFoundException or IOException but I can't from NPE or ArrayIndexOutOfBoundsException? This makes no sense.
Maybe someone has better explanation to this with some better example?
To be very simple and factual :
an unchecked exception (Runtime class and children) conveys an unexpected exception.
In general, the caller should not know how to handle it and doesn't wait for it in any of his scenarios.
a checked exception conveys a exception that you may consider as a "normal" exception and the caller know how to handle it. It is probably not the nominal case for him but the caller knows that it could happen and should prepare himself to handle it.
In your example :
nextInt() throws InputMismatchException when I type i.e. "asdf"
instead of int. InputMismatchException is RuntimeException but
according to statements above this is the first example of checked
exceptions "invalid user input".
When a method calls nextInt() the caller waits for a int value. It is the excepted scenario. If it was not the case the user would do rather : next() to retrieve a String object and try then to convert it by something that suits.
When you invoke nextInt(), the caller waits for an int as he has requested it. Force him to handle InputMismatchException as a checked Exceptionwould be counter-intuitive.
So according to that I can recover from FileNotFoundException or
IOException but I can't from NPE or ArrayIndexOutOfBoundsException?
This makes no sense.
I think JDK Exceptions as FileNotFoundException or IOException are special cases. They are probably checked not necessarily because the client of these classes waits for that the file is not found or the stream generates some exceptions during reading or writing but rather because a stream may be in a not suitable state and consequently raises exception for many external reasons (file locked, lack of right, file moved to another place or to a not reachable network and so for...).
A file that generates an exception is probably considered as something that is important to handle.
So, the JDK specification prefers that the caller handles it explicitly.
Besides, before the arrival of the try-with-resources statement, the caller should explicitly close streams in case of exceptions.
NPE and ArrayIndexOutOfBoundsException are generally programming errors. The application cannot do a processing to recover specifically errors which it doesn't know the existence. So why make them checked ?
every single exception may or may not be recoverable in your app. it always depends on the context. if some object is null and you get NPE (unchecked) it may result in an empty expression language expression (so in this particular context, this situation is perfectly recoverable). on the other hand, you may get IOException (checked) which is irrecoverable because your web application can't connect to database and therefore is useless in context of this particular web application.
Maybe someone has better explanation to this
there is a better explanation: making checked and unchecked exception was simply a wrong design decision of language authors. and it decision won't be changed as long as java remains backward compatible.
so just:
ignore this artificial division (as other modern languages decided to do)
when design your api always use unchecked
when working with checked exception, wrap them in unchecked deep down the call stack (your life will be easier)
when calling a method always think/check what exceptions it may throw (checked or unchecked) and decide for every one of them if you should handle it or rethrow/pass through

Java Type of Exception to Throw

I am trying to understand WHY to throw certain exceptions. What does it matter which one I choose to throw?
For example
//simple division method - a/b
public static double divide(double a, double b){
if(b == 0)
throw new IllegalArgumentException("b = 0");
return a/b;
}
vs
//simple division method - a/b
public static double divide(double a, double b){
if(b == 0)
throw new IllegalArithmeticException("b = 0");
return a/b;
}
(Apologies if there are errors in the code - I threw it together quickly. I'm not actually interested in the method itself.)
Does it matter which exception I choose? It seems like it could be anything - even if I used arrayIndexOutOfBoundsException, it would still stop the program and print what I want it to print.
Thanks for any help.
It's worth discussing what the difference is between a checked and an unchecked exception is, to hammer home a critical point of what exception to throw.
Let's say that you're attempting to read a file, and for whatever reason, the file isn't found. Java has a convenient FileNotFoundException that you can use to explicitly inform that the file isn't found. It's also one of the exceptions which extend (through its hierarchy) Exception, meaning that if a method states that this exception is thrown, it must be dealt with either by catching it or declaring it to be thrown elsewhere.
Then, there's the ArithmeticException, which is a runtime exception (it extends RuntimeException) - no methods need to declare this to be thrown, and you're not required to catch it explicitly, since this class of exceptions indicate an error in the code. It can come up, and in actuality, if anything were to try and catch a runtime exception, it'd look a little bit suspect.
In the context of your problem, you're basically stomping over the natural throwing of the ArithmeticException by forewarning the user of valid input. It's likely acceptable to do something like this, but for this context, you actually don't need to throw anything yourself. If someone decides to pass b = 0 into the method, they'll get the ArithmeticException.
There are existing conventions to follow based on exceptions - be as specific about the problem as possible, and offer a way to recover if appropriate - so in this scenario, if you had to throw a specific exception, I'd recommend IllegalArgumentException, since the argument b = 0 isn't acceptable when dividing or doing modulo. However, I'd also recommend that it be caught in a method outside of this instead, since the input is really suspect and it should be ideally sanitized before it makes its way to this method.
Well, from a company's point of view, it does matter what exception you're throwing. Because tecnically, you create programs for the users to work on it and if the user enters undesirable input then he/she will be able to get what mistake he/she has made.
It works as a note for the user to correct the mistakes.

Java: How to throw a custom Runtime Exception without using a throw statement?

Say, I want to prevent a divide by 3 anywhere within my current package. Usual procedure is to make an Exception subclass:
class NoDivbyThreeException extends RuntimeException {
public NoDivbyThreeException (String msg) {
super(msg);
}
}
and then throw it where required:
class CustomExceptionDemo {
public static void main(String[] args) {
int numr = 5;
int denr = 3;
try {
if (denr==3) throw new NoDivbyThreeException("Div by 3 not allowed");
else System.out.println("Result: " + numr/denr);
}
catch (NoDivbyThreeException e) {
System.out.println(e);
}
}
}
But what I want is that JVM should prevent a division by 3 anywhere inside this package without my explicit stating of the throw statement inside main(). In other words, the way JVM prevents a divide by zero by throwing exception automatically whenever it encounters such scenario, I want my program to do the same whenever it encounters a divide by 3 situation inside a package.
Is this possible? If not, please elaborate why. That will help to clear my concepts.
I don't think this is trivially possible.
You want 5 / 3 to throw an exception, right? The same as 5 / 0? According to this answer, "In an Unix environment, in which division-by-zero is signalled via SIGFPE, the JVM will have installed a signal handler which traps the SIGFPE and in turn throws an ArithmeticException."
In other words, the error caused by 5 / 0 doesn't start with the JVM, it starts with the CPU or kernel, outside of Java. You can't get the CPU or kernel to throw an exception when dividing by 3, and you can't override the behaviour of division in Java.
See also
How does Java handle division by zero?
SIGFPE
idiv JVM instruction set code
There's no way to throw an Exception without explicitly throwing it. Except for some internal Exceptions, like division by 0, which are handled by the JVM. These include NullPointerException, if not thrown by an explicit throw-statement, division by 0 and a few other errors. But these exceptions are actually created by receiving an error from the underlying platform. E.g. in case of division-by-0, the error is already generated by the CPU.
So unless your code somehow creates an error in the underlying platform, you'll have to create the error yourself. Anything else would require the JVM to be highly mutable, which wouldn't make much sense due to inconsistent behavior, which is not desirable and results in an extreme security-risk. As an example for why it's undesirable to make the JVM muteable:
Consider your example:
We could have three options to handle this (none exists, AFAIK):
alter the code in the compiler, to throw an exception, if any division by three (might) occur. Disadvantage: bloats code
alter the behavior of the JVM: even more undesirable. Consider a library that throws an exception for division by 3. Now you want to use the library in your code. But you expect normal arithmetic behavior and get some strange error when dividing by 3.
add a header to the library that describes expected behavior of the JVM. Comparable to the first option, only the load is moved from compilation and memory to the runtime and startup/on the run compilation.
To do that, you have to modify java.lang.ArithmeticException , which I believe the authorities will not let you do if they know you want to make ArithmeticException for divide by 3 :) .

How to handle exceptions in Java in functional way

How to handle exceptions in Java in functional way?
If I do:
try{
}
catch(Exception e)
{
//log it
// throw exception?
}
and catching the exceptions, what should I return:
Throw the exception?
Else send some error code ( similar to how we handle in C languages )
Because functional programming says:
A function should always return the same type.
Given this scenario, it becomes for certain given input it will throw the exception. Hence its not a pure functional style.
How one should handle this case in Java?
Well even in functional programming, exceptions are not considered as return values.
Take for instance, this segment of SML code:
fun remove_card (cs, c, e) =
case cs of
[] => raise e (* raise exception and stop execution of the function *)
| x::xs => if x = c
then xs
else x::remove_card (xs,c,e)
As you can see, when the exception is raised, we forget about the original return type of the function (a list). It is in this moment that an error situation has happened in your application and you want to handle it to avoid your application from crashing. So, you would not be breaking the purity of your functional programming, since exceptions are thrown, not returned, in order to handle the instability caused by unexpected values/behavior inside your application.
Don't both log and rethrow, if you feel like you want to put some information down and rethrow then wrap the exception. Log only if you are done dealing with this exception and plan on returning a value from the method. Not some error indication like in C, actual value. For example you tried to download something but failed, however you still have a fallback. If you are trying to indicate an error you throw an exception.
Just to add, a lot of times people deal with exceptions by logging in place and returning a null. In the vast majority of cases this is the wrong thing to do as it will only lead to frustration of dealing with NPEs in completely different places

can we throw any error or exception explicitly using throw

Since JVM Exceptions are those exceptions or errors that are either exclusively or most logically thrown by the JVM.
Programmatic exceptions are those exceptions that are thrown explicitly by application and/or API programmers using throw keyword.
Now coming to exception hierarchy: which basically divided into 3 major categories: I am relating to the above category i.e. JVM Exceptions and Programmatic Exception.
Unchecked (Error & RunTimeException) : JVM or Programmatic
Checked Exception : Programmatic.
How to differentiate between Programmer and JVM Exceptions
I am reading the above link where two things burst into my mind and I want to verify them
Can we throw any error programmatically since JVM generated exceptions can be throw programatically.
What is the significance of generating JVMException programmatically i.e. when should we throw JVM generated exceptions programmatically
In the above link " Chris Lively" wrote AsserionError can not be throw programatically which should be wrong.
The most valued answer to the referenced question says: "no such distinction exists". I can only agree with this sentence. So, (i) yes, (ii) if there is some reason to do so, say, an intermediate method calls system method, catches a "JVM" exception, and rethrows it, (iii) AssertionError well can be thrown as any other Throwable.
Your exception hierarchy can "borrow" classes from the standard library if it makes sense (e.g. IllegalArgumentException can be used for application-specific input validation and IndexOutOfBoundsException can be used for any data structure with numeric indices) but since you are concerned with exceptions thrown by your code whether these classes belong in a vaguely defined set of JVM-thrown exceptions is irrelevant.
Checked vs unchecked is also a less than fundamental distinction: the same exception class, thrown from the same places and caught in the same places with the same handling, can be either.
You might prefer the convenience of ensuring that a checked exception is caught or the convenience of not adding boring throws clauses for an unchecked exception, and you can change your mind easily.
Suppose we have a bank application that sends an alert message when the saving amount becomes zero or less then zero.
public class AmountZeroException extends Exception
{
}
public class SavingAmount
{
public private int amount;
public void PrintAmountFromSaving()throws AmountZeroException
{
System.out.println("your account balance is "+amount);
if(amount<=0)
throw AmountZEroEXception();
}
public static void main(String...k)
{
SavingAmount sa=new SavingAmount();
System.out.println(sa.PrintAmountFromSaving());
}
}
In this example above
We Can we throw any error programmatically since JVM generated exceptions can be throw programatically.
What is the significance of generating JVMException programmatically i.e. when should we throw JVM generated exceptions programmatically
hear in the above example I also can throw JVMException programatically by using any of the exception viz ArrayIndexOutOfBount or any other. but the significance depends upon the usage of the application. since my application is all about sending alert when amount becomes zero so I used Pro-grammatically my own exception.

Categories

Resources