关于异常处理:何时在Java方法声明中使用throws?

When to use throws in a Java method declaration?

所以我认为我对Java中的异常处理有很好的基本理解,但是最近我读了一些代码,这给了我一些困惑和疑虑。我的主要疑问是,在什么时候应该使用一个Java方法声明中的抛出,如:

1
2
3
4
    public void method() throws SomeException
    {
         // method body here
    }

通过阅读一些类似的文章,我收集到throw被用作一种声明,声明在方法的执行过程中可能会抛出一些异常。

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

1
2
3
4
5
6
7
8
9
10
11
     public void method() throws IOException
     {
          try
          {
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
          }
          catch(IOException e)
          {
               System.out.println(e.getMessage());
          }
     }

在这个例子中,您是否有任何理由希望使用throw?如果您只是对IOException之类的东西执行基本的异常处理,那么您只需要Try/Catch块就可以了。


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

通常,如果您不打算做任何有例外的事情,就不应该抓住它。

你能做的最危险的事就是抓住一个例外,不要用它做任何事情。

这里有一个关于何时抛出异常是适当的好讨论

什么时候抛出异常?


仅当方法引发选中的异常时,才需要在方法上包含throws子句。如果该方法引发运行时异常,则无需执行此操作。

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

如果方法捕获异常并在内部处理它(如在第二个示例中),那么就不需要包含throw子句。


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

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

  • 拆下try/catch;在这种情况下异常将由调用方法。

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


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


    这不是一个答案,而是一个注释,但是我不能用格式化的代码编写注释,所以这里是注释。

    假设有

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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;
      }
    }

    输出是

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

    该方法不声明任何"throw"异常,而是抛出它们!技巧是抛出的异常是runtimeexceptions(未选中),不需要在方法上声明。对于方法的读者来说,这有点误导,因为她看到的只是一个"throw e";语句,但没有throw异常的声明。

    现在,如果我们有

    1
    2
    3
    4
    5
    6
    7
    8
    public static void main(String[] args) throws Exception {
      try {
        throw new Exception("test");
      } catch (Exception e) {
        System.out.println(e.getMessage());
        throw e;
      }
    }

    我们必须在方法中声明"throws"异常,否则会得到一个编译器错误。


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

    类似:

    1
    2
    3
    4
    5
    6
    7
    public void method() throws Exception{
       try{
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
       }catch(IOException e){
               System.out.println(e.getMessage());
       }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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());
       }

    }


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