2012-11-28 5 views
49

私はそれが良いプログラミングの習慣であると信じているので、すべての自分の(ローカル変数またはインスタンス変数)finalを一度だけ書き込むことを意図しています。try/catchを使った最終変数の代入

はしかし、私は、変数の代入が例外を投げることができたときに、最終的な変数と作ることができないことに注意してください:

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 
} 

一時変数に頼ることなくこれを行う方法はありますか?

+1

私はあなたが一時変数なしでこれを行うことができるとは思わない。 – NPE

+8

'final int x = makeX();'は間違いなくです。 (try-catch in function) –

+2

JDKにはまだ 'tryParse'がありません(http://stackoverflow.com/questions/1486077/java-good-way-to-encapsulate-integer-parseint) 。 –

答えて

44

これを実行する方法の1つは、(final)一時変数を導入することですが、そのようにしたくないと言いました。

別の方法は、関数にコードの両方のブランチを移動させることである。

final int x = getValue(); 

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

これは実用的であるかどうかにかかわらず、正確なユースケースに依存します。

全体として、xが適切にスコープされたローカル変数である限り、最も実用的な一般的なアプローチは、finalのままにすることがあります。一方、xは、メンバ変数がある場合

は、私のアドバイスは、初期化時に非final一時的に使用するために、次のようになります。

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

私はあなたに同意しますが、これはほとんどの場合インスタンス変数で発生します。 – dtech

+0

私は静的メソッドgetValue()に静的な参照を作ることができないエラーを反映することができると推測するので、静的関数を使用すると仮定します。私は間違っている可能性がありますprivate static int getValue().. @ NPE – gks

+0

If this.xはIntegerのようなオブジェクト型で、もう少し(悲しいことに)必要です。宣言されていないx_valのままにすると、コンパイラは初期化されていない可能性があると不満を持ちます。 catchブロックのフォールバックがnullの場合は、あらかじめ初期化してnullにしておく必要があります。 –

2

ありません、それは右の場所ではありませんが、あなたが得た想像よりx = 42.いくつかの文の後にtryブロックが失敗し、catchブロックに行きます。ここでxは30となります。次にxを2回定義しました。

+9

コンパイラは、どのステートメントがどの例外をスローするかを知るのに十分にスマートです。すべてのケースで可能ではないかもしれませんが、コンパイラがデッドコードなどについてあなたに伝えることができるように、最終的に動作するかどうかを判断できるはずです。 – Stefan

+0

@Stefanが言ったことをサポートするために、ClangはSwiftのコンパイル時にこれを理解することができます。 –

関連する問題