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

所以我认为我对 Java 中的异常处理有一个很好的基本理解,但是我最近读到的一些代码让我感到困惑和怀疑。我想在这里解决的主要疑问是,人们应该在什么时候使用抛出类似下面这样的 Java 方法声明:

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

通过阅读一些类似的文章,我了解到 被用作一种声明,在方法执行期间可以抛出 有些例外

我的困惑来自于这样的代码:

     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 块,仅此而已。

128475 次浏览

If you are catching an exception type, you do not need to throw it, unless you are going to rethrow it. In the example you post, the developer should have done one or another, not both.

Typically, if you are not going to do anything with the exception, you should not catch it.

The most dangerous thing you can do is catch an exception and not do anything with it.

A good discussion of when it is appropriate to throw exceptions is here

When to throw an exception?

You're correct, in that example the throws is superfluous. It's possible that it was left there from some previous implementation - perhaps the exception was originally thrown instead of caught in the catch block.

In the example you gave, the method will never throw an IOException, therefore the declaration is wrong (but valid). My guess is that the original method threw the IOException, but it was then updated to handle the exception within but the declaration was not changed.

You only need to include a throws clause on a method if the method throws a checked exception. If the method throws a runtime exception then there is no need to do so.

See here for some background on checked vs unchecked exceptions: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

If the method catches the exception and deals with it internally (as in your second example) then there is no need to include a throws clause.

The code that you looked at is not ideal. You should either:

  1. Catch the exception and handle it; in which case the throws is unnecesary.

  2. Remove the try/catch; in which case the Exception will be handled by a calling method.

  3. Catch the exception, possibly perform some action and then rethrow the exception (not just the message)

The code you posted is wrong, it should throw an Exception if is catching a specific exception in order to handler IOException but throwing not catched exceptions.

Something like:

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

or

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

}

This is not an answer, but a comment, but I could not write a comment with a formatted code, so here is the comment.

Lets say there is

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

The output is

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

That method does not declare any "throws" Exceptions, but throws them! The trick is that the thrown exceptions are RuntimeExceptions (unchecked) that are not needed to be declared on the method. It is a bit misleading for the reader of the method, since all she sees is a "throw e;" statement but no declaration of the throws exception

Now, if we have

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

We MUST declare the "throws" exceptions in the method otherwise we get a compiler error.