異常什麼時候拋出?什麼時候本身處理?

原始問題:java

  關於異常中,什麼時候在該類中處理,什麼時候拋給調用類處理,比較糾結。好比IO中new FileInputStream(),new InputStreamReader(fStream, "UTF-8");in.readLine()等他們異常哪些本類中處理,仍是都拋給調用者。網絡

討論:框架

  李:其實對於方法中的異常處理有兩種方法:一、在該函數中用try...catch語句進行捕獲和處理。二、直接拋出異常(這種作法有一點模糊,由於並不能肯定該方法是否有異常),那麼調用該方法的調用者就要處理這個方法的異常。也就是拋出異常的狀況是拋給調用者去解決了。由於try..catch語句若是用的多的話,代碼比較繁瑣不易觀看,因此纔會有拋出一種異常這種作法吧 。運維

  胡:這樣寫行嗎?jvm

  

            FileInputStream fStream = null;
            InputStreamReader reader = null;
            BufferedReader in = null;
            try {
                fStream = new FileInputStream(path);
                reader = new InputStreamReader(fStream, "UTF-8");//將InputSteam轉換成Reader
                in = new BufferedReader(reader);    //只提供緩衝區的包裝方法
                //dosomething
            } catch (FileNotFoundException e) {
                throw e;
            } catch (SecurityException e) {
                throw e;
            } catch (UnsupportedEncodingException e) {
                throw e;
            } catch (IOException e) {
                throw e;
        }finally {
           try{ if (fStream != null) fStream.close();}catch (IOException e){log.warn("FileInputStream close failed");}
           try{ if (reader != null) reader.close();}catch (IOException e){log.warn("InputStreamReader close failed");}
           try{ if (in != null) in.close();}catch (IOException e){log.warn("BufferedReader close failed");}
        }

  李:最好別嵌套寫函數

  胡:仍是根本就不擁tryspa

  李: 要用try操作系統

  胡:直接拋給調用者。線程

  李:這個finally裏邊還有try..catch,就別這樣嵌套寫了指針

  胡: 爲何呢? 仍是無論什麼異常都拋給調用者。 我嵌套,是由於close也拋出異常。  不這樣作的話,可能某個流沒有被關閉。 因此我特別的糾結,究竟該怎麼寫,有沒有一套規範。

  李: 像這種非運行時的異常直接拋出應該沒問題

  胡: 我這樣寫,我又有點嫌它寫的太長了。 

  李: 這樣確實很繁瑣

  胡:既然要拋出,索性,所有都丟給調用者。 那try也不用了。 

  李: 若是兩種異常所有拋出,根據大小關係,調用者來兩個catch。能行嗎?

  胡:你說的意思我有點模糊

  李:  我還沒試過直接拋出兩種異常的代碼,因此我也不清楚,調用者根據捕獲的異常來處理,是否能處理呢? 

  胡: 你這個應該是能不能處理的。畢竟兩種異常調用者很難去識別是哪種異常。

    李:恩,這個有點異議, 調用者應該知道拋出的是哪一種異常啊

  胡: 個人意思好比你要拋出io和math異常,那麼就用throws Exception來拋出。  調用者接受的是Exception。  這樣能識別出是哪一種嗎? 

  李: 恩,那沒拋出math異常,在底層的方法裏邊應該用try...cathe來捕獲math異常啊

  胡: 是的。

  這個問題也不知道怎麼回事兒了,待大神解決。

  還有兩個問題:

  一、java中垃圾回收器會自動檢測再也不被引用的對象,以後釋放空間。釋放空間以後java jvm會不會像C++給指針賦值NULL?並且java jvm快到耗盡的時候才調用垃圾回收機制,若是這時由於某些狀況我必需要釋放內存,本身定義finalize方法去實現,我怎麼保證對象的空間必定被釋放掉了?也就是finalize方法不是析構函數,是怎麼被調用的?

  二、Chanel能夠用於線程間的通訊,還有哪些應用場合,有什麼好處?

(鄧維佳)回答:

1.由外界不穩定性致使的異常,應該拋出,好比IO,

2.考慮出現異常的責任,若是在系統外,拋出

3.對於異常的處理,若是以爲可能處理不當,應該printstack,同時打印context信息,便於根據日誌追查緣由

4.嵌套的trycatch,兩層就夠了,第一層是主要邏輯,第二層,我以爲更可能是語法要求。IO的異常被操做系統屏蔽的很好,除非權限問題,文件不存在,網絡不通這類,assign給運維處理一下就能解決。因此不太可能外層try關閉和嵌套層try作同一個事情,一個成功一個不成功

5.處理異常的緣由不只僅是代碼聲明可能有異常發生,更主要的是須要考慮,我處理了異常是否合理,若是自己主調方傳參有誤致使異常,在方法開頭就須要check,而後拋異常,對於不合法的請求,咱們是沒有辦法作容錯處理的

6.固然,有些狀況的異常,在業務邏輯上是合法的,可是在java語法上不合法,這個時候咱們就能夠考慮內部處理。好比傳一個數字進來,可使Integer 多是 String,多是十進制,多是十六進制,根據不一樣格式作相應轉換。或者傳入一個null,發生異常try掉,而後默認賦值爲0.。。。

 7.對於經過父類接受異常,上層框架能夠分別異常類型。可使用 e instanceof RuntimeException 或者e.getCause() 
相關文章
相關標籤/搜索