How do Checked and Unchecked Exceptions work in Java? - java

Reading about Exceptions in this book, I found this statement:
Checked exceptions are checked by the compiler at compile time.
and
The compiler does not check unchecked exceptions at compile time.
So, if also we can say that IOException or SQLException are below the Checked Exceptions class tree. How would java compiler know there will be an exception and no for IllegalArgumentException which might remain inside the code as my understanding.
Also, what does exactly the fact of being obligatory to get the Checked exceptions caught and not for Unchecked mean?

A checked exception requires that you add a throws declaration to the method signature, or you add a try catch block around it.
public void checked() throws IOException {
throw new IOException(); // compiles just fine
}
public void checked() {
try {
throw new IOException();
} catch (IOException e) {
// ...
}
}
This will not work:
public void checkedWithoutThrows() {
throw new IOException(); // will not compile
}
An unchecked exception does not need this.
public void unchecked() {
throw new RuntimeException();
}
And, just for completeness, the way to determine unchecked from checked exceptions is that unchecked exceptions all descend from RuntimeException at some point or another.

exceptions in java all work the same way.
the difference between checked and unchecked exceptions (which are all subclasses of RuntimeException) if that for a method that throws a checked exception whoever calls that method has to either try/catch the exception, or declare his own method as throwing that exception.
so if i have a method:
void throwsACheckedException() throws SomeCheckedException;
whoever calls it must do one of 2 things. either:
try {
throwsACheckedException();
} catch (SomeCheckedException e) {
//do something
}
or
void someCallingMethod() throws SomeCheckedException { //pass it on
throwsACheckedException();
}
unchecked exceptions you dont have to declare, and whoever calls the method does not have to explicitly catch. for example:
void someInnocentLookingMethod() {
throw new NullPointerException("surprise!"); //...extends RuntimeException
}
and then you can simply invoke it, without the try/catch hassle:
void unsuspectingVictim() {
someInnocentLookingMethod();
}
unchecked exceptions are usually used for things that can creep up on you at any point and so forcing developers to try/catch them would make the code very tedious (NullPointerException, for example), although there are those who thing checked exceptions are evil entirely :-)

For Checked exceptions, you see error at compile time and says that you have to handle them.
Run time exceptions do not give any error or warning to handle in your code.
Compiler expects exceptions (Checked exceptions) and asks you to handle it.

Related

Thumb rules for exceptions ("throws <some-exception>") in overridden methods

I'm trying to come up with some simple rules to remember regarding exceptions in overridden methods in Java 8.
I've seen some posts explaining this in a kind of long way or not so clear to me.
Assume when saying "Checked exception" it means the method has throws <checked-exception> in its signature etc.
Checked exceptions can stay the same or be narrowed, even to not throwing at all.
Unchecked exceptions (runtime exceptions) have no rules (can be narrowed or widened or neither).
To keep the statement simple assume that narrowing "not throwing at all" is "not throwing at all" and widening "not throwing at all" is to throw any exception (corresponding to checked/unchecked case)
Summarizing this to:
checked >= overriding-checked
unchecked, overriding-unchecked are independent
Is this all (and correct?) or are there some cases missing?
You're correct.
Let's say we have classes
public class Parent {
public void doit() throws IOException {
throw new IOException();
}
}
public class Child extends Parent {
public void doit() throws FileNotFoundException {
throw new FileNotFoundException();
}
}
Checked exceptions are the ones that you're required to handle. If Child were to throw a checked exception that is not an IOException (FileNotFoundException is an IOException, so it's okay as written), that would mean that this code lets this checked exception roam free:
Parent object = new Child();
try {
object.doit();
} catch (IOException ex) {
// thoughtful and careful handling
}
This would create a situation when a method threw a checked exception that is not declared in its throws list and defeat the definition and purpose of checked exceptions. Therefore language designers prohibited this.

Sonarqube - avoiding catch generic Exception

Sonar complains when catching the generic type Exception, but sometimes we need to do some general exception handling for ALL (even not yet recognized) exception types. What is the solution to pass this sonar check?
Unless you are invoking a method which throws Exception, there is no need to catch Exception: catch the exceptions you know about, and the compiler will tell you when you have to start handling another one.
The problem with catching "not yet recognized" Exceptions is that you lose the signal that you have to handle a new exception in a special way.
For example:
void someMethod() {
// Do stuff.
}
void callIt() {
try {
someMethod();
} catch (Exception e) {
// ...
}
}
If someMethod is now changed so that it throws, say, an InterruptedException:
void someMethod() throws InterruptedException {
Thread.sleep(1000);
// Do stuff.
}
you aren't told by the compiler that you need to add handling for the InterruptedException in callIt(), so you will silently swallow interruptions, which may be a source of problems.
If, instead, you had caught RuntimeException, or RuntimeException | IOException | OtherExceptionYouAlreadyKnowAbout, the compiler would flag that you had to change your code to handle that InterruptedException as well; or, that you can't change the signature of someMethod(), and the checked exception has to be handled there.

Why must I use try catch when I use global exception handling?

I'm beginner in Java and Android. My problem is when I use setDefaultUncaughtExceptionHandler in my code, some functions still need a try/catch block surrounding it, but I want throw all my exceptions to UncaughtException thread.
public class MyAlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Thread.setDefaultUncaughtExceptionHandler(new UnCaughtException(context));
try
{
String imageURL = MyWebService.readFeed();
DownloadAndSet.downloadFile(imageURL);
}
catch(Throwable e)
{
throw new RuntimeException(e);
}
Toast.makeText(context, "Alarm Triggered", Toast.LENGTH_LONG).show();
}
}
Java distinguishes checked and unchecked exceptions. Checked Exceptions have to be caught, no matter what.
Correction: Or you have to add the throws clause to the method. This postpones the urge to catch that exception to the caller of your method.
If you want them to be handled in the UncaughtExceptionHandler, you can "forward" them:
try{
// blah "throws some checked exception type"
} catch ( Throwable e ) {
// throw e; <- This will not work :( unless you add the "throws" clause.
throw new RuntimeException(e);
}
Unfortunately, just throwing the same Exception won't work, because you'd have to add the throws clause, which you do not want. You'll have to wrap it in a RuntimeException.
All checked exceptions in your code must be caught.
Further reading on checked vs unchecked exceptions:
http://www.javapractices.com/topic/TopicAction.do?Id=129
http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
When you call a method that throws an exception, requires you to either handle the exception using try/catch or throw the same exception.
As you don't want to handle the exception in your code and want all exceptions to be handled by your Default Exception handler so you need to add throws to all your methods where you don't want to catch the exception.
The documentation says:
Set the default handler invoked when a thread abruptly terminates due to an uncaught exception, and no other handler has been defined for that thread.
It doesn't relate to exceptions you have to catch. An example of an exception you have to catch/throw is IOException. An example of an exception you don't is NullPointerException.
So if your code causes a NullPointerException, the default handler will deal with it. If your code (potentially) causes an IOException, you have to deal with it then and there (either by catching or throwing).
What I have always done in my programs is create a exception handler method and call it every time I make a try/catch block. Many times I have had Thread.sleep() methods and I just send the exception to a common place to do "global" handling. In your global exception handler, you can also refer to this method.
Keep in mind that you might not always want to use this method because things like file streams might throw errors if a file already exists and you would want to take a different approach such as naming it something else than just stopping the program.
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
catchException(e);
}
});
try {
Thread.sleep(1000);// Just an example of a possible exception thrower
}
catch (InterruptedException e) {
catchException(e);
}
}
public static void catchException(Throwable e) {
// Deal with the exception here
System.out.println("Oh no! You broke the program!!!");
System.out.println("Here is the error btw: " + e.getMessage());
}
If you are using Eclipse, you can set the default automatic code generation for try/catch blocks to automatically include this method:
You can also set project specific settings if you don't want this behaviour for all of your projects.

Sample code to handle Exceptions

I am new to Android mobile application development.
I would like to know, how can I handle exceptions like HttpConnection related exceptions or any other exceptions? Do I need to display an AlertDialog to the user?
Kindly provide a sample code or project source code on how can I handle HttpConnection or similar type of Exceptions.
There are 2 different kinds of exceptions in Java: Checked and Unchecked. There is a big debate over which one is better to use, both arguments are good.
Basically a Checked exception is derived from java.lang.Exception and it requires that if you don't specify your method as "throws MyCheckedException" then you must catch and handle the exception within your method.
// throw the exception
void foo() throws MyCheckedException
{
throw new MyCheckedException();
}
// or handle the exception
void foo()
{
try {
throw new MyCheckedException();
} catch (MyRuntimeException e) {
e.printStackTrace();
}
}
An Unchecked exception, derived from java.lang.RuntimeException, requires neither that you specify "throws" in your method definition nor that you handle it.
void foo()
{
throw new MyUncheckedException();
}
The advantage of Checked is that the compiler will warn you when you haven't handled an exception.
The disadvantage is that you have to declare either a try/catch block or a throws for every Checked exception, and the upper level code can get pretty cumbersome, trying to handle all the different types of Exceptions.
For this reason, if you're careful you might prefer using Unchecked Exceptions.
BTW, you can only choose your exception type when you define your own.
When encountering Exceptions from Java or a 3rd party library, you have to decide how to handle it. e.g. If a 3rd party method throws CheckedException1, then you have to either handle it, or declare the calling method as "throws CheckedException1". If you want to avoid using Checked Exceptions then you can wrap it in an Unchecked Exception and throw that.
void foo() // no throws declaration
{
try {
thirdPartyObj.thirdPartyMethod(); // this throws CheckedException1
}
catch (CheckedException1 e) {
throw new MyUncheckedException(e); // this will wrap the checked in an unchecked.
}
}
Note that you can throw the Unchecked exception without the "throws" declaration. To access the original CheckedException1 from higher up, you can use the .getCause() method of your Unchecked exception.
void caller()
{
try {
foo();
} catch (MyUncheckedException e) {
CheckedException1 ce1 = e.getCause();
ce1.printStackTrace();
}
}
... but because the exception from foo() is Unchecked, you don't have to handle it or declare "throws".
Regarding logging, there are different schools of thought on this.
Log it when the exception occurs (low - level)
Log it when it reaches the top (high - level)
Log it when you have enough information to make an appropriate action and/or a log message. (mid - level)
A good policy I've found is to install an uncaught exception handler which will take care of all uncaught (obviously unchecked) exceptions. This way anything that is missed will be logged and potentially handled before crashing the system.
public class MyExceptionHandler implements UncaughtExceptionHandler
{
#Override
public void uncaughtException(Thread thread, Throwable ex)
{
ex.printStackTrace();
}
}
// In your high-level code
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
and all for Exceptions that can be handled gracefully, catch and handle them in a module where you know enough about the situation to possibly correct the problem and try again.
How you handle exception depends on the exception. If the exception is something that you cannot recover from, and the user needs to know about then you could catch the exception and show it in an AlertDialog:
try {
// do something
} catch (SomeImportantException e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("User friendly text explaining what went wrong.");
AlertDialog alert = builder.create();
alert.show();
}
For more info on the dialog, see creating dialogs.
Alternatively, if the exception is something that you can deal with, you can just log information about the exception and move on.
try {
// do something
} catch (SomeLessImportantException e) {
Log.d(tag, "Failed to do something: " + e.getMessage());
}
You could use the ACRA plugin that offers this functionality or BugSense to gather error reports.
Disclaimer: I am a founder at BugSense.

Magic Exception thrower without declaring throws Exception

I want a method that can throw any Throwable including sub classes of Exception. Ive got something that takes an exception, stashes it in a thread local, then invokes a class.newInstance. That class ctor declares that it throws Exception then takes the threadlocal and throws it. Problem is it does not work for the two declared Exceptions thrown by Class.newInstance() namely IllegalAccessException and InstantiationException.
Im guessing any other method using some sun.* class is just a hack and not really reliable.
Wrapping is not an option because that means catchers are catching a diff type and that's just too simple and boring...
static public void impossibleThrow(final Throwable throwable) {
Null.not(throwable, "throwable");
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
try {
THROW.set((Exception) throwable);
THROWER.newInstance();
} catch (final InstantiationException screwed) {
throw new Error(screwed);
} catch (final IllegalAccessException screwed) {
throw new Error(screwed);
} finally {
THROW.remove();
}
}
private final static Class<Impossible> THROWER = Impossible.class;
private final static ThreadLocal<Exception> THROW = new ThreadLocal<Exception>();
static private class Impossible {
#SuppressWarnings("unused")
public Impossible() throws Exception {
throw THROW.get();
}
}
From Java Puzzlers (puzzle 43):
public static void impossibleThrow(Throwable t)
{
Thread.currentThread().stop(t); // Deprecated method.
}
The book shows other methods of achieving the same problem, one is a simplified version of yours, the other exploits generic type erasure to throw any Throwable where an Error is expected.
If you want an Exception to bubble up through code not expecting that exception then just wrap it in a RuntimeException
} catch (RuntimeException e) {
throw e; // only wrap if needed
} catch (Exception e) {
throw new RuntimeException("FOO went wrong", e);
}
Remember to let the message be informative. Some day you will have to fix a bug based only on the information in the stack trace.
Wrapping an exception inside a RuntimeException (as suggested by Thorbjørn) is the way to go. However, you usually want to maintain the stacktrace of the original excpetion. Here's how:
public static void rethrow(final Throwable t)
{
if(t instanceof RuntimeException)
throw (RuntimeException) t;
RuntimeException e = new RuntimeException(t);
e.setStackTrace(t.getStackTrace());
throw e;
}
I patched javac to remove the error, compiled impossibleThrow(), renamed the source file to something that does not end in .java (which forces the next compile to use the existing .class) and used that.
There is some validity for this question as a debugging tool. Suppose you are working with some code that may have failed and you see that it (perhaps) catches certain exceptions and (perhaps) throws certain exceptions. You suspect that an unexpected exception was not caught. However, the underlying code/system is too complex and the bug is too intermittent to allow you to step through in the debugger. It can be usefull to add the throwing of an exception without changing the method in any other way. In this case, wrapping the exception with a RuntimeException would not work, because you want the calling methods to behave normally.

Categories

Resources