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;
}

有更好的方式吗?我不认为我必须创建一个全新的界面来解决这个问题。

4

1 回答 1

4

已检查的异常(即不是 RuntimeException 子类的异常,如 JSONException)构成方法签名的一部分。如果您调用一个引发检查异常的方法,您必须处理它,或者声明您自己抛出它。如果您自己抛出一个检查异常(就像您使用 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 回答