206 Stimmen

Sollte versuchen...fangen innerhalb oder außerhalb einer Schleife zu gehen?

Ich habe eine Schleife, die in etwa so aussieht:

for (int i = 0; i < max; i++) {
    String myString = ...;
    float myNum = Float.parseFloat(myString);
    myFloats[i] = myNum;
}

Dies ist der Hauptinhalt einer Methode, deren einziger Zweck es ist, das Array von Floats zurückzugeben. Ich möchte, dass diese Methode zurückgibt null wenn ein Fehler auftritt, also habe ich die Schleife in eine try...catch Block, etwa so:

try {
    for (int i = 0; i < max; i++) {
        String myString = ...;
        float myNum = Float.parseFloat(myString);
        myFloats[i] = myNum;
    }
} catch (NumberFormatException ex) {
    return null;
}

Aber dann habe ich auch daran gedacht, die try...catch Block innerhalb der Schleife, etwa so:

for (int i = 0; i < max; i++) {
    String myString = ...;
    try {
        float myNum = Float.parseFloat(myString);
    } catch (NumberFormatException ex) {
        return null;
    }
    myFloats[i] = myNum;
}

Gibt es irgendeinen Grund, der dafür spricht, das eine dem anderen vorzuziehen, sei es aus Leistungsgründen oder aus anderen Gründen?


Edit : Der Konsens scheint zu sein, dass es sauberer ist, die Schleife innerhalb der try/catch zu platzieren, möglicherweise innerhalb einer eigenen Methode. Es gibt jedoch immer noch eine Debatte darüber, was schneller ist. Kann jemand dies testen und mit einer einheitlichen Antwort zurückkommen?

2 Stimmen

Ich weiß nicht, wie es um die Leistung bestellt ist, aber der Code sieht mit dem Try-Catch außerhalb der for-Schleife sauberer aus.

2voto

Jamie Punkte 386

In Ihren Beispielen gibt es keinen funktionalen Unterschied. Ich finde Ihr erstes Beispiel besser lesbar.

2voto

oxbow_lakes Punkte 131223

Ich möchte meine eigenen hinzufügen 0.02c zwei konkurrierende Überlegungen, wenn es um das allgemeine Problem geht, wo die Behandlung von Ausnahmen positioniert werden soll:

  1. Je "breiter" die Verantwortung der try-catch Blocks (d.h. in Ihrem Fall außerhalb der Schleife) bedeutet, dass Sie bei einer späteren Änderung des Codes versehentlich eine Zeile hinzufügen könnten, die von Ihrer bestehenden catch blockieren; möglicherweise unbeabsichtigt. In Ihrem Fall ist dies weniger wahrscheinlich, da Sie explizit eine NumberFormatException

  2. Je "enger" die Verantwortung des try-catch Block, desto schwieriger wird das Refactoring. Vor allem, wenn Sie (wie in Ihrem Fall) eine "nicht-lokale" Anweisung innerhalb des catch Block (der return null Anweisung).

2voto

Orion Adrian Punkte 18345

Sie sollten die äußere Version der inneren Version vorziehen. Dies ist nur eine spezielle Version der Regel, alles außerhalb der Schleife zu verschieben, was man außerhalb der Schleife verschieben kann. Je nach IL-Compiler und JIT-Compiler können Ihre beiden Versionen unterschiedliche Leistungsmerkmale aufweisen oder auch nicht.

Auf eine andere Anmerkung sollten Sie wahrscheinlich float.TryParse oder Convert.ToFloat sehen.

2voto

Junaid Pathan Punkte 2980

Wenn Sie eine Ausnahme für jede Iteration abfangen oder prüfen wollen, bei welcher Iteration eine Ausnahme ausgelöst wird, und alle Ausnahmen in einer Iteration abfangen wollen, platzieren Sie try...catch innerhalb der Schleife. Dadurch wird die Schleife nicht unterbrochen, wenn eine Ausnahme auftritt, und Sie können jede Ausnahme in jeder Iteration in der Schleife abfangen.

Wenn Sie die Schleife unterbrechen und die ausgelöste Exception untersuchen wollen, verwenden Sie try...catch außerhalb der Schleife. Dadurch wird die Schleife unterbrochen und die Anweisungen nach dem catch ausgeführt (falls vorhanden).

Es hängt alles von Ihrem Bedarf ab. Ich bevorzuge die Verwendung von try...catch innerhalb der Schleife bei der Bereitstellung, da die Ergebnisse bei Auftreten einer Exception nicht zweideutig sind und die Schleife nicht unterbrochen und vollständig ausgeführt wird.

1voto

Matt Punkte 2226

Das Einrichten eines speziellen Stack-Frames für Try/Catch fügt zusätzlichen Overhead hinzu, aber die JVM kann möglicherweise die Tatsache erkennen, dass Sie zurückkehren und dies wegoptimieren.

Je nach Anzahl der Iterationen ist der Leistungsunterschied wahrscheinlich vernachlässigbar.

Ich stimme jedoch mit den anderen zu, dass der Schleifenkörper sauberer aussieht, wenn er außerhalb der Schleife liegt.

Wenn die Möglichkeit besteht, dass Sie die Verarbeitung fortsetzen wollen, anstatt bei einer ungültigen Zahl abzubrechen, sollten Sie den Code innerhalb der Schleife platzieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X