Ergebnis 1 bis 20 von 34

Thema: Exceptions

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Zitat Zitat von R.D. Beitrag anzeigen
    Uh Exceptions... Leider kann ich nur von Java berichten und was ich da gelernt habe ließ mich genau auf die Fragen stoße die du die gestellt hast: "Welchen Sinn machen sie?" In Java sind ja so gut wie alle Exceptions bereits vorhanden und eigene lohne sich imho nur für das hochpropagieren oder bei den erwähnten komplexen Rekursionen.
    Ansonsten finde ich, das es den Code unnötig auf bläht.

    Ich weiß nicht wie es in C++ ist, aber in Java gibt es ja sowieso checked und uncheked Exceptions, also solche die gefangen werden müssen und solche die nicht gefangen werden müssen. So wird man in IDE's soweiso sofort darauf aufmerksam gemacht das man hier einen Try-Block benötigt oder aber die Exception propagiert.
    Wenn ich das sagen darf: Du denkst hier falsch. Du solltest dir nicht die Frage stellen, ob Exceptions Sinn machen (bzw. welchen Sinn), sondern wann sie Sinn machen und wie man sie sinngemäß einsetzt. Exceptions sind ein mächtiges Werkzeug um deine Programme verlässlicher und wartungsfreundlicher zu machen, in dem Sinn, dass die Fehlerfindung, sowie die Fehlerbehandlung extrem vereinfacht wird im Vergleich zu allen Ansätzen bevor Exceptions eingeführt wurden.

    Ganz unabhängig von der Sprache teilst du deine Ausnahmefälle in zwei Kategorien auf:

    Ausnahmefälle von denen dein Programm sich erholen kann: Das sind alle Fehler, die mit der Korrektheit deines Programms nichts zu tun haben und Quellen wie etwa fehlerhaften Userinput, fehlende Dateien, Datenbankfehler, usw. haben. Das sind die checked Exceptions in Java.

    Und Ausnahmefälle von denen es sich nicht erholen kann: Diese sind grundsätzlich Bugs in deinem Programm (welchen Sinn würde es machen, sich von einem Bug zu erholen? Das würde den Bug nur verschleiern und dein Programm inkonsistent machen), aber auch fatale wie ein erschöpfter Heap oder Vergleichbares. Das sind die unchecked Exceptions in Java, die alle von RuntimeException ableiten. In der Regel werden diese Exceptions viel öfter geworfen als die aus der oberen Sparte, was auch ein Grund ist, wieso du sie nicht in deiner API deklarieren musst.

    Ehrlich gesagt finde ich auch nicht wirklich Gefallen daran gezwungen sein zu müssen checked Exceptions zu behandeln, aber das ist eher bedingt durch die Faulheit zu der C++ verleitet und hat nichts damit zu tun, dass ich diesen Zwang sinnlos finde. Im Gegenteil, ich finde es ist gerechtfertigt und macht das Programm viel konsistenter, beispielsweise im Gegensatz zu C++-Programmen/Bibliotheken, in denen man oft nicht weiß, ob, welche und bei welchem Input Exceptions geworfen werden. Dass C++ erlaubt mit allem zu werfen, was einem unter die Finger kommt, habe ich ja bereits erwähnt. Also ja, Javas Ideologien blähen den Code durchaus auf, aber in einem für Java akzeptablen Rahmen (bei sinngemäßem Einsatz) und bestimmt nicht unnötigerweise.

    Zitat Zitat von R.D. Beitrag anzeigen
    Ich wüsste auch nicht warum sich einfache abfragen in einen Try-Block packen soll, wenn ich doch schon mit dem If den Fehler gefangen habe.
    Du hast dich wahrscheinlich nur unglücklich ausgedrückt, aber eine Exception kannst du nicht mit einem If-Block abfangen.

    Wenn ich nochmal auf diesen Artikel verweisen darf und das Problem dort mit Int32.Parse(). Das ist zwar C#-bezogen, aber die Problematik dort ist sprach-/frameworkunabhängig, nämlich: Exceptions sollten nicht für die Flusskontrolle verwendet werden. Solltest du auf so etwas stoßen, darfst du es als Designfehler abstempeln und die API-Designer darin kritisieren, dass es ein Boolean-Rückgabewert auch getan hätte und das viel eleganter.

    Zitat Zitat von Mog Beitrag anzeigen
    Ach, asserts mit Exceptions zu vergleichen ist doch schon fast etwas unhuebsch. Die Idee ist ja doch eine Andere: Bei Exceptions ist der Fehlerfall Teil des Ergebnisses, was bei Asserts wiederum nicht der Fall ist.

    Beides hat seine Daseinsberechtigung. Dementsprechend mische ich auch beides. [...]
    Klar. Auf Assertions würde ich auch nicht verzichten, egal ob ich gerade Exceptions verwende, oder nicht. Wie der Name bereits sagt, sind sie eine Zusicherung an die Korrektheit des Programms und beim DbC-Pattern sowieso nicht wegzudenken.

    @affe (wenn ich dich so nennen darf ^^):

    Der klassische C-Ansatz ist doch eher, dass der Rückgabewert entweder in einem gültigen oder in einem ungültigen Wertebereich liegt, worauf man prüft, und der Fehlercode in einer globalen, "errno"-ähnlichen Variable gespeichert wird. Natürlich muss man immernoch den Fehlercode interpretieren, aber das kann man generalisiert erledigen.

    Ansonsten komme ich im Moment auch nicht darauf, was Mog mit "denk mal etwas zeigerlastiger" gemeint hat, wenn er nicht gerade den Umstand meinte, dass die Überprüfung schwarz-weiß ist. ^^

    Geändert von Kyuu (09.06.2010 um 03:49 Uhr)

  2. #2
    @Kyuu

    Ich hab mir den Artikel mal durchgelesen (warum nicht schon früher weiß ich auch nicht). Ist sehr interessant und offenbarend für mich gewesen. In der FH hier hatte man uns das Ganze so beigebracht das man einen Try-Block macht und in DIESEM ein Abfrage macht und die Exception wirft. Ich fand eben das immer irgendwie fraglich.

  3. #3
    Also sowas wie

    Code (C++):
     
    void MeStupid() {
        try {
            if (SomeFunc() == false) {
                throw SomeFuncFailed();
            }
        } catch (const SomeFuncFailed& e) {
            GoNuts();
        }
    }
     


    ?

  4. #4
    Zitat Zitat von Kyuu Beitrag anzeigen
    Wenn ich nochmal auf diesen Artikel verweisen darf und das Problem dort mit Int32.Parse(). Das ist zwar C#-bezogen, aber die Problematik dort ist sprach-/frameworkunabhängig, nämlich: Exceptions sollten nicht für die Flusskontrolle verwendet werden. Solltest du auf so etwas stoßen, darfst du es als Designfehler abstempeln und die API-Designer darin kritisieren, dass es ein Boolean-Rückgabewert auch getan hätte und das viel eleganter.
    Naja, ein Boolean-Rückgabewert geht da eben kaum, weil die Methode bereits ein Integer zurückgeben soll. Dass es keine einfache Möglichkeit gibt/gab (in Java ja bis heute genauso), vorher die Gültigkeit zu überprüfen (am besten auch noch, ohne dadurch die gleiche Arbeit zweimal zu erledigen, irgendwie will man ja doch noch Performance im Auge behalten) ist natürlich ungünstig, aber ich wüsste nicht wirklich, was die Methode bei einem ungültigen String machen sollte, außer eine Exception zu werfen. Und eine gute Möglichkeit, vorher die Gültigkeit zu testen, fällt mir auch spontan nicht ein, wenn man nicht für jedes Parsing ein eigenes Parser-Objekt erzeugen will.
    (Disclaimer: All das bezieht sich auf Javas Integer.parseInt(), mit der implziten Annahme, dass das in C# praktisch genauso ausschauen wird.)
    Zitat Zitat
    @affe (wenn ich dich so nennen darf ^^):

    Der klassische C-Ansatz ist doch eher, dass der Rückgabewert entweder in einem gültigen oder in einem ungültigen Wertebereich liegt, worauf man prüft, und der Fehlercode in einer globalen, "errno"-ähnlichen Variable gespeichert wird. Natürlich muss man immernoch den Fehlercode interpretieren, aber das kann man generalisiert erledigen.
    Ja, meinte ich ja, halt irgendeinen speziellen Rückgabewert zurückliefern, ungeachtet dessen ob der jetzt direkt den konkreten Fehler angibt oder auch noch eine globale Variable (= inhärentes x__X) benötigt. Jedenfalls muss man jeden Aufruf in ein if hüllen – oder alle Rückgabewerte sammeln (bei nicht aufeinander aufbauenden Aufrufen) und dann eine Riesen-if-Party am Ende veranstalten. *kratz*

    Und: Ja, darfst du. XD

    Zitat Zitat von Kyuu Beitrag anzeigen
    Also sowas wie
    […]
    ?
    Habe ich auch schon gesehen, und in manchen komplizierteren Fällen ergibt's sogar Sinn. Als bloßen Workaround für GOTOs aber natürlich absolut grauslich. x__X

  5. #5
    Zitat Zitat von drunken monkey Beitrag anzeigen
    Naja, ein Boolean-Rückgabewert geht da eben kaum, weil die Methode bereits ein Integer zurückgeben soll. Dass es keine einfache Möglichkeit gibt/gab (in Java ja bis heute genauso), vorher die Gültigkeit zu überprüfen (am besten auch noch, ohne dadurch die gleiche Arbeit zweimal zu erledigen, irgendwie will man ja doch noch Performance im Auge behalten) ist natürlich ungünstig, aber ich wüsste nicht wirklich, was die Methode bei einem ungültigen String machen sollte, außer eine Exception zu werfen. Und eine gute Möglichkeit, vorher die Gültigkeit zu testen, fällt mir auch spontan nicht ein, wenn man nicht für jedes Parsing ein eigenes Parser-Objekt erzeugen will.
    (Disclaimer: All das bezieht sich auf Javas Integer.parseInt(), mit der implziten Annahme, dass das in C# praktisch genauso ausschauen wird.)
    Man kann auch out-Parameter benutzen:
    Code (C++):
     
    class Int32 {
    public:
        // ...
        bool Parse(const string& s, int32& out) {
            // ...
        }
        // ...
    };
     

    Und diese sind alles andere als unüblich.

    Zitat Zitat von drunken monkey Beitrag anzeigen
    Habe ich auch schon gesehen, und in manchen komplizierteren Fällen ergibt's sogar Sinn. Als bloßen Workaround für GOTOs aber natürlich absolut grauslich. x__X
    Wenn man die Exception nicht fängt und nach außen propagieren lässt - und nur dann - wäre es sinnvoll, imo. Eleganter wäre es sowieso, wenn SomeFunc() selbst wirft, aber selbstverständlich kann es sein, dass diese zu irgendeiner externen Bibliothek gehört, die aus irgendeinem Grund keine Exceptions nach außen lässt, oder sie überhaupt nicht verwendet.

  6. #6
    Zitat Zitat von Kyuu Beitrag anzeigen
    Man kann auch out-Parameter benutzen:
    Ah, OK, deswegen eben mein Disclaimer. In Java gibt's die ja nicht.
    In C# wäre das dann wohl wirklich die deutlich bessere Lösung.

  7. #7
    Zitat Zitat von Kyuu Beitrag anzeigen
    Also sowas wie

    Code (C++):
     
    void MeStupid() {
        try {
            if (SomeFunc() == false) {
                throw SomeFuncFailed();
            }
        } catch (const SomeFuncFailed& e) {
            GoNuts();
        }
    }
     


    ?
    exakt so. Aber gut das ich hier was gelernt hab, jetzt kann ich das bei der Semesterausgabe anwenden.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •