3

Java で API を作成することに関して、設計レベルで疑問があります。次のようなクラスがあるとします:-

class Test
{
  public final static String DEFAULT_ENCODING = "utf-8";

  public byte[] encodeIt(String input)
  {
    try {
      return input.getBytes(DEFAULT_ENCODING);
    } catch(UnsupportedEncodingException e) {
      // do something
    }
  }
}

UnsupportedEncodingExceptionへの入力として静的文字列を使用しているため、 が発生しないことはわかっていますtoBytes。APIユーザーがそのエラーを期待してキャッチすることを望まないためencodeIt、 aを実行する必要はありません。throws UnsupportedEncodingException

そのような場合、空の catch ブロックを使用するのがベスト プラクティスですか?

4

6 に答える 6

5

空の catch ブロックを持つことは悪い考えです。あなたの推論は正しいように見えますが、この設計は、例外が発生し始めてコードがそれらを飲み込んでしまうと、ある段階で無限のデバッグと検索を引き起こします。ここで例外を RuntimeException にラップして、それをスローします。そのようです:

public encodeIt(String input)
  {
    try {
      return input.getBytes(DEFAULT_ENCODING);
    catch(UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

このようにして、例外が発生しても隠されたままになることはなく、API ユーザーが対応する必要もありません。

于 2012-12-16T10:26:57.697 に答える
5

私はこのようなことをします:

public byte[] encodeIt(String input) {
    try {
        return input.getBytes(DEFAULT_ENCODING);
    }
    catch (UnsupportedEncodingException e) {
        throw new ShouldNeverHappenException(e);
        // or: throw new IllegalStateException(e);
    }
}

(もちろん、ShouldNeverHappenException はランタイム例外です)。

このようにして、誰かがたまたま定数値を変更したり、エンコーディング引数を追加したりした場合、メソッドはすぐに失敗し、問題が見過ごされたり、ログ ファイルに埋もれたりすることはありません。

于 2012-12-16T10:25:04.140 に答える
3

そのような場合、空の catch ブロックを使用するのがベスト プラクティスですか?

それは良い考えだとは思いません。空の catch ブロックは、何かが発生する可能性があることを意味し、決してわかりません。

この例外をスローしないでください。それをキャッチしてログに記録して、それが決して起こらないという仮定を確認できるようにしますが、少なくとも、決して到着しないかどうかを知ることができます.

于 2012-12-16T10:24:42.153 に答える
2

私は通常、この質問に対する他の回答で概説されている戦略に従います (チェックされた例外を に柔らかくするなどRuntimeException)。ただし、興味深い代替手段の 1 つは、アサーションを使用することです。

public byte[] encodeIt(String input)
{
  try {
    return input.getBytes(DEFAULT_ENCODING);
  } catch(UnsupportedEncodingException e) {
    assert false;
    return null;
  }
}

-eaJVM フラグを使用してアサーションが有効になっている場合、このメソッドは、スローされたAssertionError場合にUnsupportedEncodingExceptionをスローします。面倒なのは、値 (null など) を返す必要があることです。そうしないと、コードがコンパイルされません。

したがって、おそらく次のほうが「より良い」です。

public byte[] encodeIt(String input)
{
  try {
    return input.getBytes(DEFAULT_ENCODING);
  } catch(UnsupportedEncodingException e) {
    throw new AssertionError("Unexpected.", e);
  }
}

自己文書化さRuntimeExceptionれていることを除けば、投げるのとそれほど大きな違いはありません。AssertionErrorまた、 のサブクラスであるため、通常Errorよりも根本的な失敗を表しています。このことを処理するスタックのどこか上位の節Exceptionの可能性はありません(それが発生した場合)。catch (Exception e)

于 2012-12-16T11:06:57.987 に答える
1

私が思う最善の方法は、チェック例外を避けることです。チェックを外したものを使用してください。次に、2 つの世界の最善を尽くします。実際にエラーが発生した場合はエラーを通知し、API のユーザーに例外の処理を強制しません。

于 2012-12-16T10:27:01.417 に答える
0

絶対に起こらないと確信している場合は、空の catch ブロックを残してください。ただし、実際には、後でコードを変更する場合に備えて、例外が発生したときにコンソールにログを記録することをお勧めします。

于 2012-12-16T10:24:44.700 に答える