一、InputFile类
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* @Description 构造器报错处理
* @Date 2021-01-27 9:22
*/
public class InputFile {
private BufferedReader in;
public InputFile(String fname) throws FileNotFoundException {
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 e2){
System.out.println("in.close() unsuccessful");
}
throw e;
}finally {
//如果FileReader的构造器失败了,将抛出FileNotFoundException异常。对于这个异常,
//并不需要关闭文件,因为这个文件还没有被打开。而任何其他捕获异常的catch子句必须关闭文件,
//因为在他们捕获异常时,文件已经打开了
//我们希望文件在InputFile对象的整个生命周期内都处于打开状态
//由于finally会在每次完成构造器之后都执行一遍,因此它不该是调用close()关闭文件的地方
}
}
public String getLine(){
String s;
try{
s=in.readLine();
}catch (IOException e){
throw new RuntimeException("readLine() failed");
}
return s;
}
public void dispose(){
try {
in.close();
System.out.println("dispose() successful");
}catch (IOException e2){
throw new RuntimeException("in.close() failed");
}
}
}
二、Cleanup类
/**
* @Description 构造阶段抛异常并清理
* @Date 2021-01-27 9:40
*/
public class Cleanup {
public static void main(String[] args) {
try {
//拼接绝对路径 注意替换成你自己的类路径
String path = System.getProperty("user.dir")+"\\src\\foo\\exception\\constructor\\";
InputFile in = new InputFile(path+"Cleanup.java");
try {
String s;
int i = 1;
while ((s=in.getLine())!=null)
System.out.println(i++ + " "+s);;
}catch (Exception e){
System.out.println("Caught Exception in main");
e.printStackTrace();
}finally {
in.dispose();
}
}catch (Exception e){
System.out.println("InputFile construction failed");
}
}
}
对inputfile对象的构造在其自己的try语句块中有效,如果构造失败,将进入外部的catch子句,而dispose()方法不会被调用。但是,如果构造成功,我们肯定想确保对象能够被清理,因此在构造之后立即创建了一个新的try语句块。执行清理的finally与内部的try块相关联。在这种方式中,finally子句在构造失败时时不会执行的,而在构造成功时总是执行。这种通用的清理管用法在构造器不抛出任何异常时也应该运用,其基本规则是:在创建需要清理的对象之后,立即进入一个try-finally语句块。