# Exceptions werfen + beenden



## Dag B. (15. Nov 2009)

Hallo,

mir ist der ganze Kram mit den Exceptions überhaupt nicht klar.

Bisher hab ich immer sowas gebaut:
[Java]    public static char[] return_characters()
                throws Exception
    {
        if(is_init == true)
            return characters;
        else
            throw new Exception("Chars not initialized");
        }[/code]

Ein Kumpel meinte jetzt zu mir, dass wäre ganz furchtbar, weil die Exception nicht abgefangen wird.
Das Programm soll aber definitiv abbrechen, wenn der Fehler auftritt, da ohne die characters nicht weitergearbeitet werden kann.
Wenn ich nun aber try - catch drumbaue, muss ich irgendeinen Rückgabewert angeben. Das ist in meinen Augen aber sinnlos, weil der ja nach Programmabbruch nie erreicht wird.
Also quasi so:


```
public static char[] return_characters()
    {
        if(is_init == true)
            return characters;
        else
            try {
            throw new Exception("Chars not initialized");
        } catch (Exception ex) {
            System.err.println(ex);
            System.exit(-1);
            char[] charreturn = {' ', ' '};
            return charreturn; //Needed so the method does compile, but never reached
        }
```
Ohne die unteren beiden Zeilen muckt er rum, aber die sind ja komplett sinnlos.

Wie baut man das also richtig, ohne solchen Mumpitz mit dem return anhängen zu müssen?
Ist die obere Version wirklich solch schlechter Stil und sollte vermieden werden?

Danke schonmal.


----------



## faetzminator (15. Nov 2009)

```
if (!isInit) {
    // try catch Zeugs
}
return characters;
```


----------



## Dag B. (15. Nov 2009)

Ah! Sehr gute Idee, dank dir.
Werde mal schauen ob man das bei all meinen Exceptions so einfach ummodeln kann.


----------



## Marco13 (15. Nov 2009)

Ja, eine Exception zu werfen, die man selbst in der nächsten Zeile fängt ist wirklich sinnfrei. Vor allem: Man sollte NIE (NIE NIE NIE) eine Exception werfen, sondern immer die _spezifischste_ Exception, die möglich ist. In diesem Fall wäre vermutlich sowas angebracht:

```
/**
 * ....
 * @throws IllegalStateException if this stuff is not initialized
 */
public static char[] return_characters()
{
    if(!is_init)
    {
        throw new IllegalStateException("Chars not initialized");
    }
    return characters;
}
```
(Siehe IllegalStateException (Java 2 Platform SE v1.4.2) )


----------



## Dag B. (15. Nov 2009)

Marco13 hat gesagt.:


> Ja, eine Exception zu werfen, die man selbst in der nächsten Zeile fängt ist wirklich sinnfrei.


Ja klar, aber wie machts mans sonst richtig?
Bei dem ersten von mir geposteten Quelltext wurde mir eben gesagt, dass das so auch nicht wirklich gut sei, weil ich die Exception eben überhaupt nicht abfange. :question:



> Vor allem: Man sollte NIE (NIE NIE NIE) eine Exception werfen, sondern immer die _spezifischste_ Exception, die möglich ist. In diesem Fall wäre vermutlich sowas angebracht:
> (...)


Ist noch in Arbeit, ich brauche für mein Prog im Idealfall n Haufen selbstgemachter Exceptions später, um ideal zu unterscheiden.
Versuche aber eben zur Zeit erstmal überhaupt herauszufinden, wie man es denn nun "richtig" (= in gutem Stil) macht, bevor ich anfange eben in der Spezial-Exceptions-Richtung weitergehe. 

Ich machs halt immer schön Schritt für Schritt, damit ich eben auch weiß was ich getan habe und warum Schritt 2 eben eine Verbesserung von Schritt 1 ist.
Hier wäre eben Schritt 2 ist besser als Schritt 1, da nicht alle Exceptions gefangen werden und man nachher noch weiß, was denn überhaupt gerade passiert ist. Aber dazu muss ich ja wiederrum erstmal genau verstehen, wie ich richtig mit den Exceptions (allgemein) umgehe...


----------



## Marco13 (15. Nov 2009)

Dag B. hat gesagt.:


> Ja klar, aber wie machts mans sonst richtig?
> Bei dem ersten von mir geposteten Quelltext wurde mir eben gesagt, dass das so auch nicht wirklich gut sei, weil ich die Exception eben überhaupt nicht abfange. :question:



Die Exception fängt man bestenfalls dort, wo man _selbst_ die Methode aufruft - wenn man sie denn fangen (und nicht einfach nach oben weiterlaufen lassen) will. 



Dag B. hat gesagt.:


> Ist noch in Arbeit, ich brauche für mein Prog im Idealfall n Haufen selbstgemachter Exceptions später, um ideal zu unterscheiden.



Es gibt die Empfehlung, möglichst sparsam mit eigenen Exception-Klassen umzugehen. Die Exceptions, die es schon gibt, sind sehr allgemein (IllegalState, IllegalArgument, UnsupportedOperation...), und oft kann man diese verwenden. Nur wenn du auf "höherer ebene" spezifischere Ausnahmefälle beschreiben willst, solltest du eigene Exceptions verwenden.


----------



## Dag B. (15. Nov 2009)

Marco13 hat gesagt.:


> Die Exception fängt man bestenfalls dort, wo man _selbst_ die Methode aufruft - wenn man sie denn fangen (und nicht einfach nach oben weiterlaufen lassen) will.


Ah, ok, danke. 



Marco13 hat gesagt.:


> Es gibt die Empfehlung, möglichst sparsam mit eigenen Exception-Klassen umzugehen. Die Exceptions, die es schon gibt, sind sehr allgemein (IllegalState, IllegalArgument, UnsupportedOperation...), und oft kann man diese verwenden. Nur wenn du auf "höherer ebene" spezifischere Ausnahmefälle beschreiben willst, solltest du eigene Exceptions verwenden.


Ja, ich muss mal schauen, muss ja erstmal schauen was da ist. ^^
Müsste dann eben sowas wie Einlesen eines falschen Triplets abfangen (da wiederrum: Falsche Länge oder ungültige Base ist enthalten) oder einer falschen Aminosäure. Daher denke ich mal, wäre dafür spezifische Exceptions schon besser. 
Aber bis dahin ist es bei mir auch noch etwas hin. ^^


----------



## maki (15. Nov 2009)

> Müsste dann eben sowas wie Einlesen eines falschen Triplets abfangen (da wiederrum: Falsche Länge oder ungültige Base ist enthalten) oder einer falschen Aminosäure. Daher denke ich mal, wäre dafür spezifische Exceptions schon besser.


Da fällt mir IllegalArgumentException ein.

Gehst du davon aus, dass es i.O. ist zu Versuchen ein falsches Triplet "einzulesen" bzw. ein Objekkt in einem inkonsistenten Zustand zu erzeugen?
Ich denke nicht, und damit brauchst du imho da auch keine eigene Exception, da Programmierfehler.


----------



## Dag B. (15. Nov 2009)

Uff maki, da fragst du was. ^^

Das Programm liest eine ganze Sequenz ein, diese kann eben auch nicht durch 3 teilbar sein und zB aus 100 Nukleotiden bestehen.
Das letzte Triplet hätte also eine Länge von 1. EIGENTLICH sollten meine Methoden da nicht mehr drauf zugreifen bzw zumindest nicht in Tripletform. 

Es ist also durchaus eine legale Eingabe und wenn ein Fehler im Programmtext, wenn es mal vorkommt.
Aber sollte man für den unwahrscheinlichen Fall dass es eben doch mal passiert nicht abbrechen können?


----------



## maki (15. Nov 2009)

Dag B. hat gesagt.:


> Uff maki, da fragst du was. ^^
> 
> Das Programm liest eine ganze Sequenz ein, diese kann eben auch nicht durch 3 teilbar sein und zB aus 100 Nukleotiden bestehen.
> Das letzte Triplet hätte also eine Länge von 1. EIGENTLICH sollten meine Methoden da nicht mehr drauf zugreifen bzw zumindest nicht in Tripletform.
> ...


Worauf ich hinaus wollte war, ob es normal ist mit so einer Situtuation umgehen zu müssen(also im Progrramm zu unterscheiden) oder ob es reicht dann eine IllegalArgumentException zu werfen und das war es dann mit dem Programm...

Anscheinend ist es doch normal dass so etwas vorkommen kann.
Du kannst deiner Klasse ja die Möglichkeit geben, mittzuteilen ob eine best. Methode aufgerufen werden kann, falls das ergebnis negativ ist und die Methode trotzdem aufgerufen wird, kannstz du eine Exception schmeissen.
Die Iteratoren in Java machen es ähnlich, du kannst fragen ob es ein nächstes Element gibt ([c]hasNext[/c]), bei true darf man eben die Methode ([c]next()[/c]) aufrufen, falls man bei false trotzdem versucht das nächste Element aufzurufen, gibt es eine Exception.


----------



## Dag B. (15. Nov 2009)

maki hat gesagt.:


> Worauf ich hinaus wollte war, ob es normal ist mit so einer Situtuation umgehen zu müssen(also im Progrramm zu unterscheiden) oder ob es reicht dann eine IllegalArgumentException zu werfen und das war es dann mit dem Programm...


Ah, achso.
Es ist noch nicht abgesprochen welche Fehler nun wirklich zum Abbruch führen und welche nicht.

Ansage war bisher "Mach erstmal dass alles zum Abbruch führt, die Details klären wir dann später".


----------



## Dag B. (21. Nov 2009)

Hallo,

ich hab nochmal ne Frage:
Gibt es irgendeine Seite, wo man alle Exceptions dies standardmäßig in Java gibt nachschauen kann?
In der Doku, unter Exception sind ja nur die direkten Unterklassen, die IllegalArgumentException kann ich da zB nicht finden.
Wenn ich aber nicht weiß was es noch so gibt, kann ich natürlich auch nicht schauen in welchem Paket die sind, um sie nachzuschlagen...

Aktuell benötige ich zB eine Exception welche geworfen wird, wenn eine Variable die genutzt wird, nicht intialisiert ist. 

```
private static boolean is_init;
    private static char[] legal_characters;

(...Constructor, Setter für die Variablen etc...)

    /**This function returns the legal characters
     * 
     * @return The legal characters
     * @throws Exception
     */
    public static char[] return_legal_characters()
            throws Exception
    {
        if(!is_init)
        {
                throw new Exception("Legal chars not initialized");
        }
        return legal_characters;
    }
```

Was nutzt man da am besten bzw wo kann ich mich in der Hinsicht informieren?


----------



## Painii (21. Nov 2009)

Dag B. hat gesagt.:


> Was nutzt man da am besten bzw wo kann ich mich in der Hinsicht informieren?


Schau mal nach RuntimeException (und lies dir auch noch durch was der Unterschied zu ner normalen Exception ist  )


----------

