3

私はシンプルなインターフェースを持っています

public interface Func<I, O> {
    public O apply(I i);
}

私はそのようなインターフェースを実装するプライベート(静的)クラスの束を持つクラスを持っています

import org.json.*;
public static class Baz {
    public static B Qux(String jsonSource) throws JSONException {
        JSONObject m = new JSONObject(jsonSource);
        return new Baz.Foo().apply(m);
    }

    private static class Foo implements Func<JSONObject, B> {
        public B apply(JSONObject f) {
            JSONObject x = f.getJSONObject("bar");
            /* Whatever other code in here */
            return new B(); /* Place-holder */
        }
    }
}

JSONObjectsでのほとんどすべての操作でキャッチが必要なためJSONException、コンパイラはでのキャッチされていない宣言されていない例外について文句を言いJSONObject x = f.getJSONObject("bar");ます。その特定の適用を単純にラップしtry-catchて、呼び出し元に例外を再スローできると考えて、次のように試しました。

private static class Foo implements Func<JSONObject, B> {
    public B apply(JSONObject f) {
        try {
            JSONObject x = f.getJSONObject("bar");
            /* Whatever other code in here */
            return new B(); /* Place-holder */
        catch (JSONException e) {
            throw e;
        }
    }
}

しかし、これで私は今、をerror: unreported exception JSONException; must be caught or declared to be thrown指していthrow e;ます。

なぜこれが機能しないのかわかりません。の呼び出しをさらにラップするとapply、予想どおり、新しいことは何も行われませんでした。

私の質問は次のとおりです。

  1. なぜこれが機能しないのですか?
  2. どうすれば修正できますか?

回避策は、インターフェイスに例外タイプを受け入れさせることだと思います。この構文が機能するかどうかはわかりませんが、次のような方法で何かできると思います。

public interface FuncEx<I, O, E> {
    public O apply(I i) throws E;
}

A BetterWay™はありますか?この小さな問題に取り組むためだけに、まったく新しいインターフェイスを作成する必要があるとは思いません。

4

1 に答える 1

4

チェックされた例外 (JSONException など、RuntimeException のサブクラスではない例外) は、メソッドのシグネチャの一部を形成します。チェック例外をスローするメソッドを呼び出す場合は、それを処理するか、自分でスローすることを宣言する必要があります。(catch/rethrow コードで行ったように) 自分でチェック済み例外をスローする場合でも、それを宣言する必要があります。

スローすることを宣言したくない場合は、RuntimeException でラップできます。例えば:

private static class Foo implements Func<JSONObject, B> {
  public B apply(JSONObject f) {
    try {
        JSONObject x = f.getJSONObject("bar");
        /* Whatever other code in here */
        return new B(); /* Place-holder */
    catch (JSONException e) {
        throw new RuntimeException("Could not get bar", e);
    }
  }
}

RuntimeExceptions ではなく、いつチェック済みの例外をスローするかについての考えは、多種多様です。私にとって、私の最初の指針は、呼び出し元が意味のある方法で例外に応答することを合理的に期待できる場合 (再スローするだけでなく)、それをチェック例外にすることです。それ以外の場合は、RuntimeException にします。

これは、このトピックに関する優れた記事です: http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html

于 2013-03-07T14:47:14.493 に答える