0

以下のような条件があるとしましょう。

A)

public void method() throws ... {

      XXXXXXXXXXXXXXXXXXXXXXX;
}

また

B)

public void method(){

  try{

      XXXXXXXXXXXXXXXXXXXXXXX;
   }catch(...){

      //doing something here
   }

}

でマークされた行"XXXX"が、例外をスローする可能性のあるコードの 1 行であると仮定します (この行はエラーをスローしないと仮定します)。

だから私の質問は、最初のケース(メソッド宣言時)で言及する必要がある例外と、catchブロックでキャッチする必要がある例外は何ですか??

* Exception 例外をスローしてキャッチするだけで十分であることはわかっていますが、それは良い設計ではないと思います。*

4

4 に答える 4

3

特定のメソッドがスローする、またはスローする可能性のある例外を確認する方法を尋ねているようです。実行しようとしているメソッドを教えてくれないので、答えるのは難しいです。しかし、Java の要点の 1 つは、Java が静的に型付けされていることであり、実際には、どのメソッドによってどの例外がスローされる可能性があるかを正確に知っています。呼び出す可能性のある例外メソッドを明示的にキャッチしないのはコンパイル時エラーなので、何かをキャッチする必要があるかどうかはすぐにわかります。これに対する例外はRuntimeException、意図的にコンパイル時のコントラクトの一部ではない子です。

一般に、RuntimeExceptions はキャッチされるべきではありません。それらは、プログラムが最初に入るのを許してはならないある種の状態を示しています ( nulla のトリガーをチェックしないなどNullPointerException) が、作業しているメソッドのドキュメントを確認できます彼らが何を投げるかを見るために。たとえば、String.substring()をスローする可能性があると言いますIndexOutOfBoundsException。通常、事前に必要なインデックス チェックを行う必要がありますが、事前にそれができない場合は、次のようにキャッチできます。

int userInputWeCantTrust = -4;
try {
  System.out.println("foo".substring(userInputWeCantTrust));
} catch (IndexOutOfBoundsException e) {
  System.err.println("Looks like I can't trust you, user.");
}

これを行うときは、例外の型をできるだけ明示し (例: catch IndexOutOfBoundsException、 not )、ブロックRuntimeException内にできるだけ少ないコードを配置する必要があります。tryそうしないと、伝播し続けることを許可する必要がある例外を誤ってキャッチする危険があります。


キャッチまたはスローの決定は、設計上の決定です。特定の例外を処理できる場合は、それを try-catch でラップします。そうでない場合は、ラップしません。

例 1、整数の解析、default失敗時のデフォルト:

public static int parse(String s, int default) {
  try {
    return Integer.parseInt(s);
  } catch (NumberFormatException e) {
    return default;
  }
}

例 2、ユーザー入力を解析し、メイン メソッドでエラー レポートを処理します。

// the throws note here isn't actually necessary, since NFE is a RuntimeException
public static int parse(String s) throws NumberFormatException {
  return Integer.parseInt(s);
}

public static void main(String[] args) {
  try {
    for(String s : args){
      System.out.println(parse(s));
    }
  } catch (NumberFormatException e) {
    System.err.println("You entered an invalid number.");
  }
}

それは本当にあなたのユースケースに依存します。

于 2012-07-17T19:39:35.690 に答える
1

コンパイラはこれらの質問に答えExceptionsます。コードが生成できるものをキャッチする、メソッドによってスローされると宣言する必要があります。何かを見逃した場合、コンパイラは文句を言います。RuntimeExceptionsは例外です。

唯一の選択肢は、これらの特定の例外をキャッチするか、または を使用して伝播することthrowsです。この選択 - どちらExceptionsが投げられ、どちらがキャッチされるかは、特定の目標によって異なります。

使用している API に精通している必要があり、API の一部はExceptionsAPI メソッドによってスローされますが、1 つでも見逃すとコードがコンパイルされないため、対処する機会が与えられます。

于 2012-07-17T19:40:06.047 に答える
0

発信者がメソッドに何を期待するかを考えてみてください。これは、メソッドが呼び出し元に与える「約束」であると考えてください。

ここで、何かを呼び出していると仮定すると、例外が発生する可能性があります。あなたが自分自身に尋ねるかもしれない質問は、その例外を処理し続けることによって私がした約束をまだ果たすことができるかということです。できない場合:例外をスローします(または、代わりに、MyApplicationExceptionなどでラップして別の例外をスローします)。

前に書いたように:これは設計上の質問になる可能性があります-整数解析メソッドの「約束」は「可能な限り最良の方法で文字列を数値に変換する」ことである可能性があります。その場合、例外はスローされません。どんな状況でも、または'整数の適切なエンコーディングであるはずの文字列を解析する'; その場合、例外をスローすることをお勧めします。

于 2012-07-17T19:49:12.897 に答える
0

簡単に言えば:

  1. (a) すべてのチェック済み例外
  2. (b) 処理されたすべての例外

例外を処理しない場合は、そのメソッドのドキュメント(JavaDocs など)の一部になるため、例外をスローとしてマークすることをお勧めします。

メソッドによってスローされる例外はすべて、メソッドのパブリック プログラミング インターフェイスの一部です。メソッドを呼び出す人は、メソッドがスローする可能性のある例外について知っておく必要があります。これらの例外は、メソッドのパラメーターや戻り値と同様に、そのメソッドのプログラミング インターフェイスの一部です。

ブロックの場合catch、主なことは、キャッチしているすべての例外を処理していることを確認することです (少なくとも、例外メッセージをログに記録します)。例外から回復したり、別の種類の例外をスローしたり、出力をログに記録したりすることができます。

良い例:

catch(NullPointerException e) {
    variable = "default-value";
}

catch(NullPointerException e) {
    throw new OhNoesException();
}

catch(NullPointerException e) {
    log.warn(e.getMessage());
}

ただし、例外をドロップするだけの場合は、スローする方がよいでしょう。例: 悪い (一般的な経験則として):

catch(NullPointerException e) {}
于 2012-07-17T19:39:57.453 に答える