java 构造器(constructor)
? 有一點(diǎn)很重要,即你要時(shí)刻詢問子句"如果異常發(fā)生了,所有東西能被正確清理碼?",盡管大多數(shù)情況下時(shí)非常安全的,但涉及到構(gòu)造器時(shí),問題出現(xiàn)了,構(gòu)造器會(huì)把對(duì)象設(shè)置成安全的初始狀態(tài),但還會(huì)又別的動(dòng)作,比如打開一個(gè)文件,這樣的動(dòng)作只有在對(duì)象使用完畢并且用戶調(diào)用了特殊的清理方法之后才能得以清理,如果在構(gòu)造器內(nèi)拋出了異常,這些行為也許就不能正常工作了,這意味著在編寫構(gòu)造器時(shí)要格外細(xì)心.
? 用finally也許可以解決問起,但問題并非如此簡單,因?yàn)閒inally會(huì)每次都執(zhí)行清理操作,如果構(gòu)造器在執(zhí)行過程中半途而廢,也許該對(duì)象的某部分還沒有創(chuàng)建成功就要被清理,這又會(huì)拋出新的異常(.close()也會(huì)拋出異常)
?1.構(gòu)造器拋出異常要格外注意清理方法是否有必要調(diào)用,如果方法恰當(dāng),直接向上層拋出的確能簡化編程
package exceptions; //: exceptions/InputFile.java // Paying attention to exceptions in constructors. import java.io.*;public class InputFile {private BufferedReader in;public InputFile(String fname) throws Exception {try {in = new BufferedReader(new FileReader(fname));// Other code that might throw exceptions} catch(FileNotFoundException e) {System.out.println("Could not open " + fname);// Wasn't open, so don't close it //如果沒有打開文件就不需要關(guān)閉throw e;} catch(Exception e) {// All other exceptions must close it 如果時(shí)其它異常則必須關(guān)閉文件try { //in.close()也可能拋出異常,所有要放到try塊里面in.close();} catch(IOException e2) {System.out.println("in.close() unsuccessful");}throw e; // Rethrow} finally { //由于finally總會(huì)被執(zhí)行,如果在這里關(guān)閉文件則文件剛打開還沒開始使用就關(guān)閉了// Don't close it here!!! }}public String getLine() {String s;try {s = in.readLine();} catch(IOException e) { //這這異常已被捕獲,因此getLine不會(huì)拋出任何異常throw new RuntimeException("readLine() failed");//重新拋出新的異常到上層環(huán)境,有時(shí)會(huì)簡化編程}return s;}public void dispose() {try {in.close();System.out.println("dispose() successful");} catch(IOException e2) {throw new RuntimeException("in.close() failed");}} } ///:~2.對(duì)于在構(gòu)造器階段可能拋出的異常,并且要求清理的,最安全的使用方法時(shí)使用嵌套的try子句,
package exceptions; //: exceptions/Cleanup.java // Guaranteeing proper cleanup of a resource.public class Cleanup {public static void main(String[] args) {try {InputFile in = new InputFile("Cleanup.java");try {String s;int i = 1;while((s = in.getLine()) != null); // Perform line-by-line processing here...} catch(Exception e) {//這里捕捉的時(shí)getLine()方法重新拋出的異常System.out.println("Caught Exception in main");e.printStackTrace(System.out);} finally { //如果構(gòu)造成功,則一定會(huì)執(zhí)行in.dispose()清理 in.dispose();}} catch(Exception e) { //InputFile對(duì)象在自己的try語句塊優(yōu)先,因此構(gòu)造失敗會(huì)進(jìn)入這里,而不會(huì)執(zhí)行內(nèi)部的try塊的in.colse()System.out.println("InputFile construction failed");}} } /* Output: dispose() successful *///:~?
3. 這種通用的清理慣用法在構(gòu)造器不跑出任何異常時(shí)也應(yīng)該應(yīng)用,其基本規(guī)則時(shí):在需要清理的對(duì)象之后,立即進(jìn)入一個(gè)try-finally語句塊.
//基本上,你應(yīng)該仔細(xì)考慮所有的可能細(xì)節(jié),例如本例的dispose()如果可以拋出異常,那么就需要額外的try語句塊package exceptions; //: exceptions/CleanupIdiom.java // Each disposable object must be followed by a try-finallyclass NeedsCleanup { // Construction can't failprivate static long counter = 1;private final long id = counter++;public void dispose() {System.out.println("NeedsCleanup " + id + " disposed");} }class ConstructionException extends Exception {}class NeedsCleanup2 extends NeedsCleanup {// Construction can fail:public NeedsCleanup2() throws ConstructionException {} }public class CleanupIdiom {public static void main(String[] args) {// Section 1:NeedsCleanup nc1 = new NeedsCleanup();try {// ...} finally {nc1.dispose();}// Section 2:// If construction cannot fail you can group objects:// nc5 constructor 如果對(duì)象構(gòu)造不能失敗就不需要任何catch//不能失敗的對(duì)象構(gòu)造器對(duì)象可以群眾在一起NeedsCleanup nc2 = new NeedsCleanup();NeedsCleanup nc3 = new NeedsCleanup();try {// ...} finally {nc3.dispose(); // Reverse order of construction nc2.dispose();}// Section 3:// If construction can fail you must guard each one:try {NeedsCleanup2 nc4 = new NeedsCleanup2();try {NeedsCleanup2 nc5 = new NeedsCleanup2();try { //如果nc5對(duì)象構(gòu)造失敗則會(huì)調(diào)用try塊清理,否則永不調(diào)用// ...} finally {nc5.dispose();}} catch(ConstructionException e) { System.out.println(e);} finally {nc4.dispose();}} catch(ConstructionException e) { // nc4 constructor System.out.println(e);}} } /* Output: NeedsCleanup 1 disposed NeedsCleanup 3 disposed NeedsCleanup 2 disposed NeedsCleanup 5 disposed NeedsCleanup 4 disposed *///:~
?
轉(zhuǎn)載于:https://www.cnblogs.com/jiangfeilong/p/10303179.html
總結(jié)
以上是生活随笔為你收集整理的java 构造器(constructor)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项目管理中风险评价的必要性
- 下一篇: Golang 学习资料