构建器问题

class InputFile {
	private BufferedReader  in ;
	// constructor 
	InputFile(String fname) throws Exception{
		try {
			in = new BufferedReader(new FileReader(fname)) ;
			// other code that might throw exceptions 
		} catch (FileNotFoundException e) {
			System.out.println("can not open "+ fname) ;
			// not open ,so not close 
			throw e ;
		}catch (Exception e) {
			// all other exceptions must close 
			try {
				in.close() ;
			} catch (IOException e2) {
				System.out.println("in.close() failed") ;
			}
			throw e ;
		}finally{
			// do not close here 
		}
	}
	
	String getLine (){
		String s ;
		try {
			s = in.readLine() ;
		} catch (IOException e) {
			System.out.println("readLine failed") ;
			s = "failed" ;
		}
		return s ;
	}
	
	void cleanup (){
		try {
			in.close() ;
		} catch (IOException e) {
			System.out.println("in.close failed") ;
		}
	}
}

public class Cleanup{
	
	public static void main(String [] args ){
		try {
			InputFile in = new InputFile("Cleanup.java" );
			String s ;
			int i =1;
			while((s= in.getLine())!= null){
				System.out.println(i +":"+ s);
				i++;
			}
			in.cleanup() ;
		} catch (Exception e) {
			System.out.println("catch in main") ; 
			e.printStackTrace() ;
		}
	}
}

  

为违例编写代码时,我们经常要解决的一个问题是:“一旦产生违例,会正确地进行清除吗?”大多数时候
都会非常安全,但在构建器中却是一个大问题。构建器将对象置于一个安全的起始状态,但它可能执行一些
操作——如打开一个文件。除非用户完成对象的使用,并调用一个特殊的清除方法,否则那些操作不会得到
正确的清除。若从一个构建器内部“掷”出一个违例,这些清除行为也可能不会正确地发生。所有这些都意
味着在编写构建器时,我们必须特别加以留意。

 

对 FileReader 来说,除非转移并用它创建一个能够实际
与之“交谈”的 BufferedReader,否则便没什么用处。注意 InputFile 的一个好处就是它同时合并了这两种
行动。
若 FileReader 构建器不成功,就会产生一个 FileNotFoundException(文件未找到违例)。必须单独捕获这
个违例——这属于我们不想关闭文件的一种特殊情况,因为文件尚未成功打开。其他任何捕获从句(catch)
都必须关闭文件,因为文件已在进入那些捕获从句时打开。

用户使用完毕 InputFile 对象后,必须调用 cleanup() 方法,以便释放由 BufferedReader 以及/或者
FileReader 占用的系统资源(如文件句柄)

posted @ 2015-03-16 23:37  chuiyuan  阅读(189)  评论(0编辑  收藏  举报