Advanced   Java   Services throws throw Back Next Up Home


throws

Statt try-catch zu verwenden kann man auch versuchen, die Ausnahme weiterzuwerfen. Dies geschieht mit dem Schlüsselwort throws. Dann wird sozusagen die nächsthöhere Instanz damit beauftragt, die Ausnahme zu behandeln (oder wieder weiterzuwerfen). In der Regel steht die kritische Anweisung in einem Konstrukor oder in einer Methode. Will man keine try-catch-Behandlung, so kann man die Signatur einer Methode um eine sogenannte throws-Klausel ergänzen. Wir betrachten das folgende Beispiel.

import java.io.*;

public class ThrowsDemo
{
   public static void main(String args[])
   {
      ThrowsDemo td = new ThrowsDemo();

      td.openFile();
      // unreported exception IOException
      // must be caught or declared to be thrown
   }

   public void openFile(String datei) throws IOException
   {
      FileReader fr = new FileReader(datei);
      // ...
   }

} // end class

Anstatt in der Methode openFile() die Ausnahme abzufangen werfen wir Sie mit einer throws-Klausel weiter. Jetzt muß der Aufrufer der Methode die Exception behandeln. Entweder er setzt try-catch ein oder er wirft die Ausnahme wieder weiter. Dann muß die Methode, in der das kritische Statement steht mit einer entsprechenden throws-Klausel versehen werden. Hier müßte man dann die main-Methode mit einer entsprechenden throws-Klausel versehen.

import java.io.*;

public class ThrowsDemo
{
   public static void main(String args[]) throws IOException
   {
      ThrowsDemo td = new ThrowsDemo();

      td.openFile();
   }

   public void openFile(String datei) throws IOException
   {
      FileReader fr = new FileReader(datei);
      // ...
   }

} // end class

Eine Ausnahme solange nach oben zu werfen bis man schließlich die Signatur von main ergänzt ist zwar zulässig, hat aber mit echter Ausnahmebehandlung nichts mehr zu tun, denn der ClassLoader, der die main-Klasse lädt, macht natürlich keine Ausnahmebehandlung. Tritt die Ausnahmesituation ein, wird das Programm sofort beendet. Für eine echte Ausnahmebehandlung braucht man also spätestens in main ein try-catch.

Einige Beispiele für Methoden bzw. Konstruktoren aus der Klassenbibliothek, deren Signaturen um eine throws-Klausel ergänzt sind.


Aus dem Quellcode der Klasse Integer
public static int parseInt(String s) throws NumberFormatException
{
   return parseInt(s,10);
}

Aus dem Quellcode der Klasse FileReader
public FileReader(String fileName) throws FileNotFoundException
{
   super(new FileInputStream(fileName));
}

Aus dem Quellcode der Klasse File
private synchronized void readObject(java.io.ObjectInputStream s)
   throws IOException, ClassNotFoundException
{
   //...
}

Das letzte Beispiel zeigt, daß man auch mehrere Ausnahmen werfen kann, man trennt sie einfach durch ein Komma.



throw

Bleibt noch das Schlüsselwort throw. Mit throw kann man selbst Ausnahmen auslösen. Dazu muß man zuerst ein Ausnahmeobjekt erzeugen und es dann mit throw werfen. Das folgende Beispiel zeigt den Anfang des Quellcodes der Methode parseInt aus der Klasse Integer


Aus dem Quellcode der Klasse Integer
public static int parseInt(String s, int radix)
   throws NumberFormatException
{
   if (s == null)
   {
      throw new NumberFormatException("null");
   }

   if (radix < Character.MIN_RADIX)
   {
      throw new NumberFormatException
                  ("radix " + radix + " less than Character.MIN_RADIX");
   }

   if (radix > Character.MAX_RADIX)
   {
      throw new NumberFormatException
                  ("radix " + radix + " greater than Character.MAX_RADIX");
   }

   // ...
}

Hier wird zunächst überprüft, ob beim Aufruf der Methode halbwegs vernünftige Parameter übergeben wurden. Ist dies nicht der Fall, wird das eigentliche parsen garnicht begonnen. das ist eine typische Programmsituation. Erst wenn man sicher ist, daß die Eingabeparameter gewisse Mindestanforderungen erfüllen, beginnt man mit der eigentlichen Arbeit. Wie man sieht, reicht ein Konstruktoraufruf alleine nicht aus, das Objekt muß explizit geworfen werden und man braucht für jedes Objekt ein eigenes throw. Wirft man eine checked exception, so muß man diese mit throws in der Signatur der umhüllenden Methode angeben (man könnte sie theoretisch mit try-catch abfangen, aber das macht in dieser Situation keinen Sinn). Wirft man dagegen eine unchecked exception, so braucht man die Signatur der Methode nicht ergänzen, man kann es aber der Deutlichkeit halber tun. Die folgende Methode wirft drei Ausnahmen. Nur InterruptedException muß mit throws in der Signatur ergänzt werden.

public void throwing(int a)
   throws InterruptedException
{
   if (a==0)
      throw new NullPointerException();  // unchecked exception

   if (a==1)
      throw new IndexOutOfBoundsException();  // unchecked exception

   if(a==2)
      throw new InterruptedException(); // checked exception
}

Zusammenfassung
Valid XHTML 1.0 Strict top Back Next Up Home