2012-05-05 13 views
4

引数のないコンストラクタが不可能な例外をスローするか、空のキャッチブロックを持つ方が良いでしょうか?私はこのようなクラスを持っているとしましょう。 Javaの引数のないコンストラクタ:不可能な例外をスローするか、空のキャッチブロックがありますか?

public class Foo { 
    private int num; 
    private String numString; 

    public Foo() throws NumberFormatException { 
     setNum("1"); 
    } 

    public void setNum(String s) throws NumberFormatException { 
     // In reality, complex code goes here 
     num = Integer.parseInt(s); 
     numString = s; 
    } 
} 
コンパイラは、(何も起こりません)NumberFormatExceptionをスローするか、try/catchブロックを持つようにコンストラクタに強制します。しかし、空のキャッチブロックを作成するのは正しいでしょうか?それは通常悩まされますか?

public Foo() { 
    try { 
     setNum("1"); 
    } 
    catch (NumberFormatException e) { } 
} 

fooがライブラリのクラスになりますし、他の人がそれを使用することに注意し、その引数なしのコンストラクタが不可能な例外をスロー持つことは混乱するだろうしてください。また、実際の例外はNumberFormatExceptionではなくカスタム例外であり、ライブラリのユーザにとってはもっと混乱させる可能性があり、必要でないときにカスタム例外を読み上げなければならないと感じるかもしれないことにも注意してください。

答えて

12

NumberFormatExceptionRuntimeExceptionであるため、throws句にリストする必要はありません。ただそこには存在しないふりをしてください。これは、メソッドとコンストラクタの両方に適用されます。

RuntimeExceptionのサブクラス(RuntimeExceptionを含む)は、未チェックの例外です。つまり、コンパイラはtry/catch句でチェックするよう強制しません。対照的に、RuntimeExceptionのサブクラスではないExceptionは、簡単には十分にチェックされた例外と呼ばれます。それは(つまり、RuntimeExceptionのサブクラスではない)をチェック例外だったが、あなたはそれをトリガーすることができませんでしたことを確認した場合

することは、それをキャッチするために安全であると思います。それを完全に飲み込むのではなく、チェックされていない例外の周りに包むのが最善でしょう。

try { 
    thisCodeCanNeverThrowAnIOException(); 
} 
catch (IOException e) { 
    throw new AssertionError(e); // juuust in case! 
} 

今、あなたのコードがコンパイルされ、あなたがスローされることを期待することはありません例外のthrows句を持っていない、まだいくつかのバグや将来の変化によって、その例外は終わりを行い、場合重大なエラーを隠しません。うんざりする

(私はもともとコード例throw new RuntimeException(e)でしたが、Stephen CとPeter LawreyはJava 1.4.2以降ではAssertionErrorが優れていると指摘しました)。

+3

+1 - "これは決して起こらないはずです"というより具体的な意味を持つ "AssertionError"を投げることを好む。 –

+0

@StephenCこの問題は、 'AssertionError'が' Throwable cause'引数を取ることができないということです。つまり、最初の例外がどのようにスローされるのかを示すスタックトレースはありません。これは非常に有用なデバッグ情報です。特に投げられなかったと確信していた場合は特にそうです! – yshavit

+0

私の実際の例外は、チェックされた例外で、RuntimeExceptionとして機能しました。ありがとう! – anomal

1

sは、現在の文字列ではなくsetNum()で整数を渡すのはなぜでないのですか?整数は常に文字列に対して解析可能です。

+0

私の実際のメソッドは、引数としてStringの配列をとり、配列内のすべてのStringを検証する必要があるか、または例外をスローします。私はこの例を使った方が簡単です。 – anomal

1

これはあなたのビジネスケアや個人的なコーディングスタイルに依存しますが、例外を投げることを選択した場合は、渡されたパラメータが間違っているあなたは今例外をスローすることができます。

NumberFormatExceptionがスローされなければならない場合は、これをキャッチするだけです。あなたのライブラリクラスや呼び出し側クラス、あるいはあなたが知らないどこかにあるかもしれません。それなしではプログラムはダウンするでしょう。

あなたのケースでは、番号のない文字列を正当な値と見なしますか?そうであれば、あなたのパッケージに例外を残す責任があります。

0

私はこう言うでしょう:決して空のキャッチブロック(どんな場合でも)。 @yshavitが指摘しているように、考えられるエラーを呑み込むのは良い習慣ではありません。使用

はスティーブン-cは言った@として、主張する一歩前進代替されているが、この解決策は2つの欠点ました:

  1. そうかもしれないあなたが、「運用/プロダクション」サーバー上で有効になっていませんアサート実際には空のキャッチブロックと非常に似ています
  2. サーバー上で有効になっている場合、このコードを実行中にエラーが発生すると、アプリケーションに不具合があることが示されます(「これは決して起こらないはずですが、起こります!だから...」

@yshavitプロポーザルのお勧めです。

関連する問題