Rethrow exception in java

2020-02-01 01:45发布

I have a very simple question about re-throwing exception in Java.

Here is the code snippet:

public static void main(String[] args) throws FileNotFoundException {
    try {
        FileReader reader = new FileReader("java.pdf");
    } catch (FileNotFoundException ex) {
        throw ex;
    }
}

public static void main(String[] args) throws FileNotFoundException {        
        FileReader reader = new FileReader("java.pdf");        
}

Why do we need to re-throw ex in the first version while the second version looks more elegant? What might be the benefits and which version is preferred over the other?

7条回答
ゆ 、 Hurt°
2楼-- · 2020-02-01 02:02

In addition to wanting to do something with the exception before exiting - like logging, the other time you would do something like that is if you want to wrap it as a different exception, like:

try {
    FileReader reader = new FileReader("java.pdf");
} catch (FileNotFoundException ex) {
    throw new ServletException(ex);
}
查看更多
乱世女痞
3楼-- · 2020-02-01 02:08

I would only catch/rethrow an exception (instead of just throwing it) if I wanted to do something else in the catch block - for example, write a logging statement before rethrowing.

查看更多
叛逆
4楼-- · 2020-02-01 02:11

You are right. Second version is better. Moreover the first version does not make any sense. It does the same except the stack trace of the exception will be "wrong".

There are the following reasons to "re-throw" exceptions:

  1. If you have something to do before.
  2. If you catch exception of one type and throw exception of other type:

example:

try {
   // do something
} catch (IOException ioe) {
    throw new IllegalStateException(ioe);
}
查看更多
虎瘦雄心在
5楼-- · 2020-02-01 02:15

Both versions will output the same stacktrace

without try/catch

import java.io.FileNotFoundException;
import java.io.FileReader;

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
//        try {
            FileReader reader = new FileReader("java.pdf");
//        } catch (FileNotFoundException ex) {
//            throw ex;
//        }
    }
}

will output

Exception in thread "main" java.io.FileNotFoundException: java.pdf (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at java.io.FileReader.<init>(FileReader.java:58)
    at Test.main(Test.java:7)

with try/catch/throw same exception

import java.io.FileNotFoundException;
import java.io.FileReader;

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
        try {
            FileReader reader = new FileReader("java.pdf");
        } catch (FileNotFoundException ex) {
            throw ex;
        }
    }
}

will output exactly the same as before

Exception in thread "main" java.io.FileNotFoundException: java.pdf (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at java.io.FileReader.<init>(FileReader.java:58)
    at Test.main(Test.java:7)

try/catch/throw wrapping exception

An advisable approach is to throw your own exceptions. wrap the exception you just caught into it if you want to provide details of the root cause (might be wanted or not wanted)

import java.io.FileNotFoundException;
import java.io.FileReader;

public class Test {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("java.pdf");
        } catch (FileNotFoundException ex) {
            throw new RuntimeException("Error while doing my process", ex);
        }
    }
}

You can clearly see the top-level issue (my process did not complete), and the root cause that led to it (java.pdf file not found)

Exception in thread "main" java.lang.RuntimeException: Error while doing my process
    at Test.main(Test.java:9)
Caused by: java.io.FileNotFoundException: java.pdf (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at java.io.FileReader.<init>(FileReader.java:58)
    at Test.main(Test.java:7)
查看更多
迷人小祖宗
6楼-- · 2020-02-01 02:19

The question is why you think you need to rethrow the exception. Did Eclipse suggest surrounding with try-catch? In practice we rarely rethrow the same exception, but very often catch one and throw another that wraps the first one, especially if the wrapper exception is unchecked. This happens whenever you have calls declaring checked exceptions, but the method you write those calls in doesn't declare those exceptions:

public int findId(String name) {
  try {
    return db.select("select id from person where name=?", name);
  } catch (SQLException e) {
    throw new RuntimeException(e);
  }
}
查看更多
兄弟一词,经得起流年.
7楼-- · 2020-02-01 02:25

In the example given, re-throwing the Exception serves no purpose.

Doing this can be useful if the method that catches and then re-throws the exception needs to take some additional action upon seeing the Exception, and also desires that the Exception is propagated to the caller, so that the caller can see the Exception and also take some action.

查看更多
登录 后发表回答