thinking in java 中的一个例子,这个惯用法保证了在构造方法中抛出异常的代码能够正常处理:
1 package test ; 2 3 import java.io.BufferedInputStream; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.IOException; 7 8 class InputFile { 9 PRivate BufferedInputStream in = null ;10 private File file = null ;11 public InputFile(String filepath ) throws IOException {12 file = new File(filepath) ;13 in = new BufferedInputStream(new FileInputStream(file));14 15 }16 public String getFileContent() throws IOException {17 byte[] content = new byte[(int)file.length()] ;18 in.read(content) ;19 return new String(content) ;20 }21 public void dispose() throws IOException{22 in.close(); 23 System.out.println("dispose successful ! ");24 }25 }26 public class Cleanup{27 public static void main(String[] args) {28 try{29 InputFile input = new InputFile("这里写文件路径") ;30 try{31 String content = input.getFileContent() ;32 }catch(Exception e ){33 e.printStackTrace();34 }35 finally{36 input.dispose(); 37 }38 }catch(Exception e){39 e.printStackTrace();40 }41 }42 }
在main方法中可以确保文件正常打开才执行dispose方法,也就是关闭文件的方法。
还有将InputFile类构造方法中的异常抛出是有意义的,书上原话为:
“异常被重新抛出,对于构造器而言这么做是很合适的,因为你总不希望去误导调用方,让他以为这个对象已经创建完毕,可以使用了”
上面的编码格式可以扩展广泛一点,基本规则是:“在创建需要清理的对象之后,立即进入一个try-fianlly语句块”:
分为两种情况,1 : 构造方法可能会失败也就是可能会抛出异常 2 : 构造方法不会失败
当构造方法不会抛出异常的情况:
1 class TestClean1 { 2 public TestClean1() { 3 // 比如打开了很多资源 4 } 5 /** 6 * 执行该类的清理工作 7 */ 8 public void clean(){} 9 }10 class TestClean2 {11 public TestClean2() {12 }13 /**14 * 执行该类的清理工作15 */16 public void clean(){}17 }18 public class TestCleanup {19 public static void main(String[] args) {20 21 TestClean1 clean1 = new TestClean1() ;22 TestClean2 clean2 = new TestClean2() ;23 try{24 // 在这里执行clean1和2的代码25 }finally{26 clean1.clean();27 clean2.clean();28 }29 }30 }
当构造器会出现错误的时候:
1 class TestClean1 { 2 public TestClean1() throws Exception { 3 throw new Exception() ; 4 } 5 /** 6 * 执行该类的清理工作 7 */ 8 public void clean(){} 9 }10 class TestClean2 {11 public TestClean2() throws Exception {12 throw new Exception() ;13 }14 /**15 * 执行该类的清理工作16 */17 public void clean(){}18 }19 public class TestCleanup {20 public static void main(String[] args) {21 try{22 TestClean1 clean1 = new TestClean1() ;23 try{24 TestClean2 clean2 = new TestClean2() ;25 try{26 // 执行clean1和clean2的代码27 }finally{28 clean2.clean();29 }30 }catch(Exception e ){31 System.out.println("clean2构造失败");32 e.printStackTrace();33 }finally{34 clean1.clean();35 }36 }catch(Exception e ){37 System.out.println("clean1构造失败");38 e.printStackTrace();39 }40 }41 }
当构造方法抛出异常表示没有正常打开资源,也就不需要清理。上面代码保证了两个对象都能够正确的清理。
新闻热点
疑难解答