There are two kinds of exceptions in Java:
When a checked exception is thrown inside the run()
method of a Thread
object, we have to catch and treat them, because the run()
method doesn't accept a throws
clause. When an unchecked exception is thrown inside the run()
method of a Thread
object, the default behaviour is to write the stack trace in the console and exit the program.
Fortunately, Java provides us with a mechanism to catch and treat the unchecked exceptions thrown in a Thread
object to avoid the program ending.
In this recipe, we will learn this mechanism using an example.
The example of this recipe has been implemented using the Eclipse IDE. If you use Eclipse or other IDE such as NetBeans, open it and create a new Java project.
Follow these steps to implement the example:
First of all, we have to implement a class to treat the unchecked exceptions. This class must implement the
UncaughtExceptionHandler
interface and implement theuncaughtException()
method declared in that interface. In our case, call this classExceptionHandler
and make the method to write information aboutException
andThread
that threw it. Following is the code:public class ExceptionHandler implements UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { System.out.printf("An exception has been captured\n"); System.out.printf("Thread: %s\n",t.getId()); System.out.printf("Exception: %s: %s\n",e.getClass().getName(),e.getMessage()); System.out.printf("Stack Trace: \n"); e.printStackTrace(System.out); System.out.printf("Thread status: %s\n",t.getState()); } }
Now, implement a class that throws an unchecked exception. Call this class
Task
, specify that it implements theRunnable
interface, implement therun()
method, and force the exception, for example, try to convert astring
value into anint
value.public class Task implements Runnable { @Override public void run() { int numero=Integer.parseInt("TTT"); } }
Now, implement the main class of the example. Implement a class called
Main
with amain()
method.public class Main { public static void main(String[] args) {
Create a
Task
object andThread
to run it. Set the unchecked exception handler using thesetUncaughtExceptionHandler()
method and start executingThread
.Task task=new Task(); Thread thread=new Thread(task); thread.setUncaughtExceptionHandler(new ExceptionHandler()); thread.start(); } }
Run the example and see the results.
In the following screenshot, you can see the results of the execution of the example. The exception is thrown and captured by the handler that writes the information in console about Exception
and Thread
that threw it. Refer to the following screenshot:
When an exception is thrown in a thread and is not caught (it has to be an unchecked exception), the JVM checks if the thread has an uncaught exception handler set by the corresponding method. If it has, the JVM invokes this method with the Thread
object and Exception
as arguments.
If the thread has not got an uncaught exception handler, the JVM prints the stack trace in the console and exits the program.
The Thread
class has another method related to the process of uncaught exceptions. It's the static method setDefaultUncaughtExceptionHandler()
that establishes an exception handler for all the Thread
objects in the application.
When an uncaught exception is thrown in Thread
, the JVM looks for three possible handlers for this exception.
First, it looks for the uncaught exception handler of the Thread
objects as we learned in this recipe. If this handler doesn't exist, then the JVM looks for the uncaught exception handler for ThreadGroup
of the Thread
objects as was explained in the Processing uncontrolled exceptions in a group of threads recipe. If this method doesn't exist, the JVM looks for the default uncaught exception handler as we learned in this recipe.
If none of the handlers exits, the JVM writes the stack trace of the exception in the console and exits the program.
The Processing uncontrolled exceptions in a group of threads recipe in Chapter 1, Thread Management