44

メソッドシグネチャのスローとJavaのスローステートメントの違いを明確にしようとしています。メソッドシグネチャのスローは次のとおりです。

public void aMethod() throws IOException{
    FileReader f = new FileReader("notExist.txt");
}

スローステートメントは次のとおりです。

public void bMethod() {
    throw new IOException();
}

私の理解ではthrows、メソッド署名は、メソッドがそのような例外をスローする可能性があるという通知です。throwステートメントは、状況に応じて作成されたオブジェクトを実際にスローするものです。その意味で、メソッド内にthrowステートメントが存在する場合、メソッド シグネチャ内の throw は常に表示される必要があります

ただし、次のコードはそうしていないようです。コードはライブラリからのものです。私の質問は、なぜそれが起こっているのですか?概念を間違って理解していますか?

このコードは、java.util.linkedList からのコピーです。@著者 ジョシュ・ブロック

 /**
 * Returns the first element in this list.
 *
 * @return the first element in this list
 * @throws NoSuchElementException if this list is empty
 */
public E getFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}

答えの更新:

更新 1 : 上記のコードは次と同じですか?

// as far as I know, it is the same as without throws
public E getFirst() throws NoSuchElementException {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}

更新 2 : チェックされた例外の場合。署名に「スロー」が必要ですか? はい。

// has to throw checked exception otherwise compile error
public String abc() throws IOException{
    throw new IOException();
}
4

4 に答える 4

6

Vidya はあなたの質問に素晴らしい答えを提供してくれました。

最も重要な言葉は、「最後のポイントは、例外がチェック済み例外である場合にのみ、throws で例外を宣言する必要があるということです」です。

これが何を意味するのか、コード例を示します。データを渡すために FileOutputStream を使用したいとします。関数は次のようになります。

public void saveSomeData() throws IOException {
  FileInputStream in = null;
  FileOutputStream out = null;

  try {
    in = new FileInputStream("input.txt");
    out = new FileOutputStream("output.txt");
    int c;

    while ((c = out.read() != -1) {
      in.write(c);
    }
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    // Close in
    if (in != null) {
      in.close(); // <-- If something bad happens here it will cause runtime error!
    }
    // Close out
    ...
  }
}

throws IOExceptionを提供せず、finally{} ステートメント内で何か問題が発生した場合、エラーが発生することを想像してみてください。

于 2015-02-07T14:09:52.957 に答える
3

throwあなたが正しく推測したように、メソッド署名の属性は、メソッドが呼び出し元によってキャッチされなければならない例外を発生させるというコンパイラへのヒントです。この種の例外、つまりチェック済み例外と呼ばれるものは、呼び出し元が常にキャッチするか、呼び出し元に再度ディスパッチする必要がありますこれはコンパイラ レベルのものであり、シグネチャはメソッドがスローできる例外try-catchを指定します。メソッドの振る舞い。

一方、他の例外、つまり未チェックまたはランタイム例外(NoSucheElementException一例) は、さまざまな状況から発生するため、強制的に指定する必要のない例外です。

概念的な違いは、チェックされた例外は通常、開発者が何らかの方法で処理する必要がある例外的な状況について警告するために使用されますが、チェックさIOExceptionれていないものは実際のエラーです (NullPointerExceptionあなたの例のようにNoSuchElementException)

于 2013-10-05T03:14:28.987 に答える
2

RuntimeExceptions は try-catch ブロックで処理する必要がないため、スローされたと宣言する必要はなく、NoSuchElementExceptionRuntimeExceptionそれを拡張するためです。

于 2013-10-05T03:12:08.630 に答える