Advanced   Java   Services UncaughtExceptionHandler Back Next Up Home


UncaughtExceptionHandler

Die Signatur von run() enthält keine throws-Klausel, wenn man weiß, daß eine Exception geworfen wird, kann man ein try-catch schreiben. Wenn aber unvorhergesehene Exceptions auftreten, dann wird der Thread mit einer Exception beendet und das führt dann zu einem Programmabbruch. Mit einem UncaughtExceptionHandler kann man hier ein sauberes Ende herbeiführen.


Die Methode setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

Mit dieser Methode kann man einen Handler übergeben, der für ein sauberes Ende sorgt. Per default ist kein Handler gesetzt. Thread.UncaughtExceptionHandler ist ein inneres Interface der Klasse Thread. Dieses Interface ist ein Functional Interface ( siehe Java1.8 ) und vereinbart daher nur eine Methode mit dem Namen void uncaughtException(Thread t, Throwable e). Ein gesetzter Handler verhindert einen Programmabbruch selbst wenn er leer ist oder wie im folgenden Beispiel nur aus Konsolmeldungen besteht.

Das Beispiel zeigt die Vorgehensweise.

Der Handler, der das Interface implementiert bringt in diesem Beispiel einige Informationen über den Thread und die Exception.

public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler
{
  @Override
  public void uncaughtException(Thread th, Throwable ex)
  {
    System.out.println("uncaughtException() happened");
    System.out.println("Thread    = " + th );
    System.out.println("Exception = " + ex);
    System.out.println("Threadstate: " + th.getState());
    System.out.println("end UncaughtExceptionHandler");
  }
}

Das Runnable mit einem run(), das eine RuntimeException auslöst.

public class MyRunnable implements Runnable
{
  @Override
  public void run()
  {
    System.out.println(Thread.currentThread().getName() + " started, will throw an Exception in 3 seconds");
    try{ TimeUnit.SECONDS.sleep(3); } catch(InterruptedException ex) {  }
    String s = "abc";
    Integer.parseInt(s);  // löst die RuntimeException aus
    System.out.println("end run"); // wird nicht passieren
  }

}

Das Main-programm setzt den Handler, startet den Thread und wartet auf seine Beendigung

public static void main(String[] args)
{
  Thread th = new Thread( new MyRunnable() );
  // setzen des handlers
  // der handler meldet die exception und gibt infos darüber
  th.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler() );
  th.start();
  System.out.println("MyRunnable gestartet.");
  try
  {
    th.join();
  }
  catch(InterruptedException ex)
  {
    ex.printStackTrace();
  }

  System.out.println("end main");
}

Ablauf

MyRunnable gestartet.
Thread-0 started, will throw an Exception in 3 seconds
uncaughtException() happened
Thread    = Thread[Thread-0,5,main]
Exception = java.lang.NumberFormatException: For input string: "abc"
Threadstate: RUNNABLE
end UncaughtExceptionHandler
end main

Kommentiert man die Zeile, in der der Handler gesetzt wird (*) aus, so ergibt sich folgender Ablauf

MyRunnable gestartet.
Thread-0 started, will throw an Exception in 3 seconds
Exception in thread "Thread-0" end main
java.lang.NumberFormatException: For input string: "abc"
  at java.lang.NumberFormatException.forInputString(Unknown Source)
  at java.lang.Integer.parseInt(Unknown Source)
  at java.lang.Integer.parseInt(Unknown Source)
  at MyRunnable.run(MyRunnable.java:16)
  at java.lang.Thread.run(Unknown Source)

Man sieht deutlich, daß die Exception zum Programmabbruch führt.

Valid XHTML 1.0 Strict top Back Next Up Home