2012-11-28 12 views
49

Da ich glaube, dass es eine gute Programmierpraxis ist, mache ich alle meine (lokalen oder Instanz-) Variablen final, wenn sie nur einmal geschrieben werden sollen.Endgültige Variablenzuweisung mit try/catch

Allerdings merke ich, dass, wenn eine variable Zuordnung eine Ausnahme auslösen, können Sie kann nicht gesagt machen Variable final:

final int x; 
try { 
    x = Integer.parseInt("someinput"); 
} 
catch(NumberFormatException e) { 
    x = 42; // Compiler error: The final local variable x may already have been assigned 
} 

Gibt es eine Möglichkeit, dies zu einer temporären Variablen ohne Rückgriff zu tun? (oder ist dies nicht der richtige Ort für einen endgültigen Modifikator?)

+1

Ich bezweifle, dass Sie dies ohne eine temporäre Variable tun können. – NPE

+8

'final int x = makeX();' definitiv. (try-catch in function) –

+2

Erschreckend, dass das JDK [noch kein 'tryParse' hat] (http://stackoverflow.com/questions/1486077/java-good-way-to-encapsulate-integer-parseint) . –

Antwort

44

Eine Möglichkeit, dies zu tun, ist durch die Einführung einer (nicht final) temporäre Variable, aber Sie sagten, Sie wollten das nicht tun.

Eine andere Möglichkeit ist es, beide Zweige des Codes in eine Funktion zu bewegen:

final int x = getValue(); 

private int getValue() { 
    try { 
    return Integer.parseInt("someinput"); 
    } 
    catch(NumberFormatException e) { 
    return 42; 
    } 
} 

Ob dies praktisch ist von der genauen Anwendungsfall abhängt.

Alles in allem, so lange x eine lokale Variable mit angemessenem Gültigkeitsbereich ist, könnte der praktischste allgemeine Ansatz darin bestehen, es nicht zu lassen.

Wenn auf der anderen Seite ist x eine Membervariable, mein Rat wäre ein nicht final vorübergehend während der Initialisierung zu verwenden sein:

public class C { 
    private final int x; 
    public C() { 
    int x_val; 
    try { 
     x_val = Integer.parseInt("someinput"); 
    } 
    catch(NumberFormatException e) { 
     x_val = 42; 
    } 
    this.x = x_val; 
    } 
} 
+0

Für einen lokalen Bereich stimme ich Ihnen zu, jedoch tritt dies am häufigsten bei Instanzvariablen auf. – dtech

+0

Ich denke, es könnte einen Fehler widerspiegeln kann nicht einen statischen Verweis auf die nicht-statische Methode getValue() machen, so dass wir die statische Funktion verwenden sollen, kann ich falsch sein private static int getValue() .. @ NPE – gks

+0

Wenn this.x ist ein Objekttyp wie Integer, dann brauchst du etwas mehr (leider). Wenn Sie x_val undeclared belassen, wird der Compiler beschweren, dass er möglicherweise nicht initialisiert wurde. Wenn der Fallback für den catch-Block null ist, müssen Sie ihn auf null vorinitialisieren und entweder redundant im catch für Klarheit (das ist meine Präferenz) zuweisen oder einen leeren catch haben. –

2

Nein es nicht der richtige Ort ist, stellen Sie bekamen mehr dann 1 Statement in Ihrem try und catch Block, der erste sagt: x = 42. Nach einigen anderen Statements versagt der try Block und geht zum catch Block, wo Ihr Saying x = 30 ist. Nun haben Sie x zweimal definiert.

+9

Der Compiler ist schlau genug zu wissen, welche Anweisungen welche Ausnahmen auslösen. Es ist vielleicht nicht in allen Fällen möglich, aber genau so wie der Compiler Ihnen in einigen Fällen über toten Code etc. erzählen kann, sollte es in der Lage sein herauszufinden, ob das Finale funktionieren würde. – Stefan

+0

Um zu unterstützen, was @Stefan gesagt hat, kann Clang dies herausfinden, wenn er Swift kompiliert. –

Verwandte Themen