情况如上图,问g()应该抛出f()的异常还是处理掉f()的异常?
一、如果h()无需知道g()是否成功或者是否出错,或者h()对g()出错与否不能控制和解决,那么g()就无需向h()报告异常
二、如果h()在运行中需要知道g()是否成功以及可以对g()出错进行处理,那么g()不能自己处理掉异常,应该往上抛出。
三、g()可以将f()的异常如下处理:
private void g(){
try {
f();
} catch (Exception e) {
throw new RuntimeException("RuntimeException in g() !", e);
}
}
这样,h()既可以选择处理g()中抛出的异常,如:
private void h(){
try{
g();
} catch(RuntimeException re){
try{
throw (Exception)re.getCause();//找出原始的异常
} catch(Exception e){
System. out.println("g() Exception in h() has been dealt");//处理原始的异常
}
}
}
也可以直接放弃处理该异常,此时java编译器不会强制要求处理g()中的异常!
综上所述,g()是否继续抛出异常,这本身不取决于自己,而是取决于上层调用函数
package inputfile;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class InputFile {
private BufferedReader in ;//代表资源
//构造函数,应该自行负责资源打开失败时的资源释放问题,它只应该向上层表示
//资源是否打开成功,至于成功与否的其他扫尾问题不应该由高层处理
public InputFile(String fname) throws Exception {
try {
in= new BufferedReader(new FileReader(fname));//打开资源
} catch (FileNotFoundException e) {
System. out.println("Could not open " +fname);
throw e;
} catch(Exception e){
try {
in.close();
} catch (IOException e1) {
System. out.println("in.close() unsuccessful" );
}
throw e;
}
}
//资源处理函数,如果处理出错或者发生特殊情况是有理由让上层知道在资源处理过程
//中究竟发生了什么,这样上层才能进一步采取措施
public String getLine() throws IOException{
String s;
s= in.readLine();
return s;
}
//资源释放函数,不应该往上抛出异常,因为本类已经是处理资源的基础类,如果
//连本类都不知道怎么释放资源,那么即使往上抛出异常,上层也不知道如何处理
public void dispose(){
try {
in.close();
} catch (IOException e) {
throw new RuntimeException("in.close() failed !");
}
}
}
package inputfile;
public class Test {
public static void main(String[] args) {
try {
InputFile input=new InputFile( "dfjkd");
try{
String s=input .getLine();
} catch(Exception e){
e.printStackTrace();
} finally{
input.dispose();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}