86

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

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

通过阅读一些类似的帖子,我收集到throws被用作一种声明,在方法执行期间可能会抛出SomeException 。

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

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

在这个例子中你有什么理由想要使用throws吗?似乎如果您只是对诸如 IOException 之类的东西进行基本的异常处理,那么您只需要 try/catch 块就可以了。

4

7 回答 7

84

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

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

你能做的最危险的事情就是捕获一个异常而不用它做任何事情。

关于何时适合抛出异常的一个很好的讨论是here

什么时候抛出异常?

于 2010-12-08T21:26:58.910 回答
26

如果方法抛出检查异常,您只需要在方法上包含 throws 子句。如果该方法抛出运行时异常,则无需这样做。

有关已检查与未检查异常的一些背景信息,请参见此处:http: //download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

如果该方法捕获异常并在内部处理它(如第二个示例中所示),则无需包含 throws 子句。

于 2010-12-08T21:32:08.630 回答
9

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

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

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

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

于 2010-12-08T21:32:21.837 回答
2

您发布的代码是错误的,如果捕获特定异常以处理 IOException 但抛出未捕获的异常,它应该抛出异常。

就像是:

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

}

于 2012-10-18T23:19:08.623 回答
2

你是对的,在那个例子中throws是多余的。它可能是从以前的一些实现中遗留下来的——也许异常最初是被抛出的,而不是在 catch 块中捕获的。

于 2010-12-08T21:29:27.813 回答
1

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

于 2010-12-08T21:31:28.490 回答
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(未选中)。对于该方法的读者来说,这有点误导,因为她看到的只是“扔 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;
  }
}

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

于 2017-11-30T15:51:38.973 回答