【问题标题】:When throwing an exception from a java method, will a more general one override a more specific one?从 java 方法抛出异常时,更通用的方法会覆盖更具体的方法吗?
【发布时间】:2019-09-06 05:45:23
【问题描述】:

确切的错误是:“抛出列表中已经有一个更一般的异常,'java.lang.exception'”

我有这样的方法:

public String myMethod() throws FileNotFoundException, IOException, Exception {
        try{  
            // DO STUFF

        }catch(FileNotFoundException e){
            // DO STUFF  
          throw new FileNotFoundException("custom message", e);

        }catch(IOException e){
          // DO STUFF
          throw new IOException("custom message", e); 

        }catch(Exception e){
          throw new Exception("custom message", e); 
        }
        return myString;
}

Intellij 告诉我前两个是多余的,因为我最后有更通用的Exception,是这样吗?
即使我明确地抛出IOException,该方法是否会抛出Exception?
还是无论如何都会抛出通用异常,所以我什至不需要Exception?

【问题讨论】:

  • 你的问题毫无意义。这是先到先得的原则。一次只能抛出一个异常。不,如果您有 IOException,则不会抛出 new Exception("", e),如果您没有专门捕获 IOException 并且您的代码会抛出一个
  • “它们并不总是可靠的”??你是什​​么意思?它们非常可靠,如果 IDE 不可靠,您真的认为 IDE 会发展成为专业环境中最常用的工具之一(尤其是如果您必须付费才能获得所有功能)?一个更好的问题是:如果您不相信 IntelliJ 的可靠性,为什么还要使用它?
  • @Stultuske 是的,我知道。但是,据我所知,linter 说,因为我在throws 部分中有Exception,并且比IOException 更通用,所以我应该从顶部的throws 中删除IOException。但我不想检查堆栈中更靠前的是哪种类型的异常,我宁愿从这里抛出正确的异常..
  • @Stultuske 不可靠是错误的,这是一个糟糕的短语,我会删除它。
  • 所以问题是,当我不想时,intellij 会提示我抛出更一般的异常。声明一个方法只抛出最一般的情况并不总是最好的,当内部实际抛出的异常更具体时。如果你这样做,它对调用者是不透明的。在这种情况下,这是我对 linter 的问题。

标签: java exception throws


【解决方案1】:

IntelliJ 确实告诉您第二个 catch 块 从未 到达。 FileNotFoundException 是IOException 的子类型,因此如果发生此类异常,则执行第一个 catch 块,因为IOException 匹配正在抛出的FileNotFoundException。

catch 块总是按照它们被声明的顺序进行评估。这意味着如果你交换两个 catch 块,它就会起作用。

更新

根据您的评论,IntelliJ 注意到您的不是 try-catch 块,而是 throws 子句。

那是因为对于checked exceptions,Java 强制您声明它们以在方法声明中抛出。只需要在throws 子句中声明最一般 异常。 IDE 是说因为你声明了Exception 被抛出,所以没有必要同时声明Exception 的任何子类,因为这些情况已经被Exception 覆盖了。

但是,您可能仍希望这样做的原因是向调用者提供更多信息。请参阅软件工程 StackExchange 上的 this question and answer。

更多信息:


我强烈建议您捕捉一个过于笼统的异常。这通常是代码异味。

【讨论】:

  • 对不起,我写错了例子,我的代码是正确的。我现在已经修好了。 linter 显示以下内容:“抛出列表中已经有一个更一般的异常,'java.lang.exception'”并且顶部的 FileNotFoundException 和 IOException 显示为灰色。
  • 非常感谢。我刚刚在测试自己,看来如果我在抛出 Exception 的方法中抛出 IOException ,我仍然可以捕获 IOException 而无需先检查它是什么。我会看一下软件工程 StackExchange。是的,当我问这个问题时,这是我关心的问题。我宁愿在可能的情况下抛出/捕获特定异常,并且想知道如果方法定义仅显示throws Exception,我是否可以捕获IOException。看来我可以。
  • 但是问题是其他人看不到我专门抛出IOException而不进入我的代码查看。
  • @bot_bot 这就是 Javadoc 发挥作用的地方:您应该记录您的方法应该做什么、它期望什么以及它如何处理异常。
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多