你的位置:首页 > Java教程

[Java教程]在构造方法中存在异常的惯用处理法


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 }

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