什么时候在Java方法声明中使用抛出?


82

因此,我认为我对Java中的异常处理有很好的基本了解,但是最近我正在阅读一些使我有些困惑和怀疑的代码。我要在这里解决的主要疑问是,一个人何时应该使用以下方法抛出Java方法声明:

    public void method() throws SomeException
    {
         // method body here
    }

通过阅读一些类似的文章,我收集到的引发信息被用作一种声明,表明可以在方法执行期间引发SomeException

我的困惑来自一些看起来像这样的代码:

     public void method() throws IOException
     {
          try
          {
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
          }
          catch(IOException e)
          {
               System.out.println(e.getMessage());
          }
     }

在此示例中,您是否有任何理由要使用抛出?看来,如果您只是对IOException之类的东西进行基本的异常处理,则只需要try / catch块即可。

Answers:


79

如果捕获的是异常类型,则无需抛出异常,除非要重新抛出它。在您发布的示例中,开发人员应该做一个或另一个,而不是两者都做。

通常,如果您不打算执行任何例外操作,则不应捕获它。

您可以执行的最危险的操作是捕获异常,而不对其执行任何操作。

在这里很好地讨论了何时应该抛出异常

什么时候抛出异常?


2
是否应该在方法签名中用“ throws”声明未检查的异常,还是将“ throws”仅用于检查的异常?
科迪2014年

这个答案没有直接解决问题的中心方面:throws关键字的使用。
布伦特·布拉德本

@hvgotcodes如果我捕获到异常却什么也不做会怎样?
Manoj

@manoj可能会导致事情崩溃,并且由于丢失重要信息而无法弄清楚。在某些时候(不一定是Java)可以捕获异常并且不执行任何操作,但是应该记录在案。例如,在javascript中,您可以尝试调用可能不存在的功能,具体取决于浏览器。这不一定是需要引起注意的错误。
hvgotcodes


9

您查看的代码并不理想。您应该:

  1. 捕获并处理异常;在这种情况下,throws则不需要。

  2. 删除try/catch; 在这种情况下,异常将由调用方法处理。

  3. 捕获异常,可能执行一些操作,然后重新引发异常(而不仅仅是消息)


2

您是正确的,在该示例throws中多余。很有可能以前的某些实现将其保留在那里-也许该异常最初是抛出的,而不是被捕获在catch块中。


1

在您给出的示例中,该方法永远不会抛出IOException,因此声明是错误的(但有效)。我的猜测是,原始方法引发了IOException,但随后对其进行了更新以处理其中的异常,但声明未更改。


1

您发布的代码是错误的,如果为了处理IOException而捕获了特定异常,则应引发Exception,但不会引发未捕获的异常。

就像是:

public void method() throws Exception{
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println(e.getMessage());
   }
}

要么

public void method(){
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println("Catching IOException");
           System.out.println(e.getMessage());
   }catch(Exception e){
           System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc.");
           System.out.println(e.getMessage());
   }

}


1

这不是答案,而是评论,但是我无法使用格式代码编写评论,因此这里是评论。

可以说有

public static void main(String[] args) {
  try {
    // do nothing or throw a RuntimeException
    throw new RuntimeException("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

输出是

test
Exception in thread "main" java.lang.RuntimeException: test
    at MyClass.main(MyClass.java:10)

该方法不声明任何“抛出”异常,而是抛出它们!诀窍是抛出的异常是RuntimeExceptions(未经检查),不需要在方法中声明。对于该方法的读者来说,这有点误导,因为她所看到的只是一个“ throw e”。声明,但没有声明throws异常

现在,如果我们有

public static void main(String[] args) throws Exception {
  try {
    throw new Exception("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

我们必须在方法中声明“ throws”异常,否则会出现编译器错误。


编译器进行了令人惊讶的复杂静态分析,以决定是否throws需要。
布伦特·布拉德本
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.