构造器的功能是把对象设置成安全状态,但还会有别的动作,比如打开一个文件,这样的动作只有在对象使用完毕并且用户调用了特殊的清理方法之后才能得以清理。如果在构造器内出现了异常,这些清理行为也许就不能正常工作了。这意味着在编写构造器时候要格外细心。请看下面的例子
package com.bird.thinking; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class InputFile { /** * @use 构造器的异常处理 * @param args * @author Bird */ private BufferedReader in; public InputFile(String FileName) throws Exception{//带一个参数的构造器 try{ in = new BufferedReader(new FileReader(FileName)); }catch(FileNotFoundException e){ System.out.println("Could not Open " + FileName);//它现在没有打开文件,所以不需要关闭 throw e;//一定要抛出异常,方便使用者知道构造函数会有异常 }catch(Exception e){//抛出其他异常说明文件已经打开,则需要关闭 try{ in.close(); }catch(IOException e2){ System.out.println("in.close() unsuccessful"); } throw e; } } public String getLine(){//出现异常则抛出运行错误异常 String s = null; try{ s = in.readLine(); }catch(IOException e){ throw new RuntimeException("readLine() failed"); } return s; } public void dispose(){ try{ in.close(); System.out.println("dispose close successful"); }catch(IOException e2){ throw new RuntimeException("in.close() unsuccessful"); } } public static void main(String[] args) {//使用这个类的构造函数 try{ InputFile in = new InputFile("d:\\测试.txt");//构造函数的初始化需要单独放在一个try-catch模块里面 try{ String s = null; while((s = in.getLine()) != null){ System.out.println(s); } }catch(Exception e){ System.out.println("Cauch Exception in main"); e.printStackTrace(System.out); }finally{ in.dispose(); } }catch(Exception e){ System.out.println("InputFile Construction failed"); } } }
当这个文件找不到时候,运行结果如下
Could not Open d:\试.txt InputFile Construction failed 当这个文件找到的时候,运行结果如下测试 dispose close successful
1.可以看出,如果构造器失败了,将抛出FileNotFoundException异常,而其他的异常会提示,并且关闭输入流
2.调用的时候多了一个try-catch模块,这是为了不要误导使用者,让他认为对象已经创建完毕,可以使用了
3.总之,使用构造器里面的异常一定要注意,嵌套try-catch,和抛出处理完的异常