在构造方法中存在异常的惯用处理法

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 }

当构造方法抛出异常表示没有正常打开资源,也就不需要清理。上面代码保证了两个对象都能够正确的清理。

原文地址:https://www.cnblogs.com/caiyao/p/4737133.html