Java 从泛型方法传播异常而不抛出声明

Java 从泛型方法传播异常而不抛出声明,java,exception,Java,Exception,我有一个简单的界面 public interface Func<I, O> { public O apply(I i); } 然而,我现在得到了错误:未报告的异常JSONException;必须被抓住或声明被抛出指向抛出e 我不明白为什么这样不行。如预期的那样,进一步包装对apply的调用没有产生任何新的效果 我的问题是: 为什么这样不行 我怎样才能修好它 我认为一种解决方法是让我的接口接受异常类型。我不确定这种语法是否有效,但我想我可以按照 public interfac

我有一个简单的界面

public interface Func<I, O> {
    public O apply(I i);
}
然而,我现在得到了
错误:未报告的异常JSONException;必须被抓住或声明被抛出
指向
抛出e

我不明白为什么这样不行。如预期的那样,进一步包装对
apply
的调用没有产生任何新的效果

我的问题是:

  • 为什么这样不行
  • 我怎样才能修好它
  • 我认为一种解决方法是让我的接口接受异常类型。我不确定这种语法是否有效,但我想我可以按照

    public interface FuncEx<I, O, E> {
        public O apply(I i) throws E;
    }
    
    公共接口函数{
    公共O应用(I)抛出E;
    }
    
    有更好的办法吗™? 我不认为我必须创建一个全新的接口来增加这一点。

    检查异常(即不是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);
        }
      }
    }
    
    私有静态类Foo实现Func{
    公共B应用(JSONObject f){
    试一试{
    JSONObject x=f.getJSONObject(“bar”);
    /*这里还有其他代码吗*/
    返回新的B();/*位置保持架*/
    捕获(JSONException e){
    抛出新的RuntimeException(“无法获取bar”,e);
    }
    }
    }
    
    关于何时抛出检查异常而不是运行时异常的想法是多种多样的。对我来说,我的第一个指导原则是,如果您可以合理地期望调用方以有意义的方式响应异常(不仅仅是重新抛出异常),那么就将其设为检查异常。否则,将其设为运行时异常

    这是一篇关于这个主题的优秀文章:

    public interface FuncEx<I, O, E> {
        public O apply(I i) throws E;
    }
    
    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);
        }
      }
    }