1. 程式人生 > >第七章 java 基礎

第七章 java 基礎

無意間都到一篇《走心的安卓工程師跳槽經驗分享》,發現自己工作幾年了,技術方面雖然有了飛躍的進步,可是不知道自己的技術到了什麼地步,每個方面我都涉及到了,但都不深,這大概是初級工程師的詬病吧!

即使知道也不知道從何下手,非常感謝《走心的安卓工程師跳槽經驗分享》的作者!

感興趣的朋友和我一起走下去吧!

07異常處理

理論上異常處理劃分為兩個模型(中止模型與繼續模型),但實際使用方面我們對中止模型用的比較多,這個模型比較實用,而繼續模型則不是那麼的應用普遍,多少是耦合的過於緊密。

處理機制 為什麼要自定義自己的Exception ,Java Exception機制與傳統的C語言的異常處理機制有什麼不同,這種Exception機制的意義在什麼地方?接下來咱就來和你一起探討Exception 的優缺點。

早期的C語言的異常處理機制,通常是我們人為的對返回結果加一些標誌來進行判定,比如發生錯誤返回什麼標誌,正常情況下我們又是返回什麼標記,而這些都不是語言本身所賦予我們的,而對於C語言這種機制又有什麼問題哩?為什麼新一代的語言 Java Ruby C# 等都用Exception機制而不是維持C語言的老樣子?這些都是我們需要思考的問題。

C語言的異常處理機制全是我們人為的定義,這樣就會造成業務邏輯的主線受到異常處理的牽制,或者說是我們難免會將注意力轉移,並且造成業務邏輯與異常處理之間有很大程度上的纏繞。

中止模型 假設錯誤非常嚴重,已至你無法在回到錯誤發生的地方,也就是說,這段程式經過判斷認為,他已經沒有辦法挽回,於是就丟擲異常,希望這個異常不要在回來,這也是Java 當前所採用的模式。

繼續模型 這種模型的主旨是恢復當前的執行環境,然後希望能夠重新回到錯誤的發生地,並希望第二次的嘗試能夠獲得成功,這種模型通常為作業系統所應用。

好處: 讓異常處理與業務邏輯的主線分離,我們對可以遇見的異常作分支處理,其實將業務邏輯與異常處理分離也是Exception設計的主旨,其次Java Exception 不需要像C語言那樣在程式的多個地方去檢測同一個錯誤,並就地作異常的處理,相比老式的錯誤處理,現行的錯誤處理的結構則來的更加清晰。

用法

  public class T {
        UserManager manager = new UserManager();
        public void testloadUser(String username, String password, String name, String email) {
            try {
                manager.loadUser(username);
            }
            catch (UserNotFoundException unfe) {
            }
        }
    }    
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
    public class UserManager {
        public User loadUser(String username) throws UserNotFoundException {
            Connection con = null;
            PreparedStatement pstmt = null;
            try {
                pstmt = con.prepareStatement("select User form user where id=1");
                pstmt.setString(1, username);
                ResultSet rs = pstmt.executeQuery();
                if (!rs.next()) {
                    throw new UserNotFoundException();
                }
                return null;
            } catch (SQLException ex) {
                return null;
            }
        }
    }
    
    class User {
    }
    
    public class UserNotFoundException extends Exception {
        private Throwable nestedThrowable = null;
        public UserNotFoundException() {
            super();
        }
        public UserNotFoundException(String msg) {
            super(msg);
        }
    }

在這裡我們自定義了自己的UserNotFoundException異常,這樣在客戶呼叫loadUser()方法的時候Java就可以強制檢測到這個UserNotFoundException異常,這樣我們就可以作相應的處理工作,在這裡應該可以看到testloadUser這裡對UserNotFoundException這個異常有一個分支處理,這樣的異常分支處理是不是很清晰哩,在此我不對他作解釋,因為實在比較簡單,其實美好的東西在我看來都有一個度,當這個度被你所打破後,那麼他將不會再美好,Exception機制的應用也是,而這個度就需要你自己在實際專案中去斟酌了,接下來我就會闡述Exception的缺點。

Java 有將受控異常和執行時異常模型都實現,Rod Johnson認為在Java中主要實現執行時異常模型,至於受控異常則為輔,而Bruce Eckel則來的更為偏激一些,他認為Java只需要實現執行時異常模型,而受控異常沒有必要繼續存在,為什麼他們都這麼認為哩,而且Bruce Eckel 之前很是推崇受控異常地,其實也沒那麼多為什麼,這些思維的改變不過就是他們在實踐當中發現了很多問題且對Exception 認識也更深刻了唄,所以說大師不是天生的,大師也需要學習,在這裡我更贊成Rod Johnson 對Exception的觀點,OK,廢話我也不多說了,說說我認識中的Java Exception 缺點!

1 、當一個方法中被過多的丟擲受控異常,那麼在別人呼叫的時候會造成try/catch語句的泛濫,甚至經常出現巢狀異常,使得程式碼的可讀性下降。

2、在某些方面檢測系統的異常也並沒有實際的意義,因為當出現這種異常的時候一般代表問題很嚴重我們無法恢復,如:捕獲資料庫SQLException異常,該異常對我們來說沒太大意義,因為錯誤資訊太模糊,通常都是一些堆疊上的資訊,看Rod Johnson 設計的關於JDBC方面的Exception Framework相信會對您產生很大的觸動。

3、在大型系統中受控異常同時會造成異常處理類的泛濫,其實本人並沒有介入過什麼大型的Java 系統的設計工作,所以我也無從對這指三道四,沒有實踐就沒有發言權,但我在一般的系統已經多少看到了一些這樣的問題。 最後希望我的這篇解說能夠進一步的增加你對 Java Exception 機制的瞭解,如果您還是不太清楚Exception機制,那麼我推薦你看 《Thinking in Java》 這本書的第三版以及Rod Johnson的 expert one on one 系列書籍

建立Exception 時建議日常開發中需要注意以下幾點:

一、Throw new exception 曾經看過有人在簡單的函式內瘋狂的使用throw new 參與業務邏輯。比如,以下程式碼: 邏輯類似以上程式碼,就是一個單一的函式,每當我看到這樣的單一函式,總是覺得很奇怪。或許是自身水平有限,似乎難以理解為了catch住一個exception物件需要那麼大費周章的去throw new 麼?個人認為如果某方法內巢狀的方法根據業務邏輯主動丟擲異常,讓外層方法截獲到這個異常,此時被巢狀的方法方可使用throw new …

二、丟擲不該丟擲的Exception 上文中的DoSomeThing函式如果在catch時不進一步封裝,直接把Excepiton拋到UI層,又或者直接顯示給客戶。如果異常堆疊中提示某些敏感資料。比如SQL查詢語句、WebService URI或POST資訊等。這些敏感資訊應該永遠不讓客戶知道,暴露出這些資訊有可能對系統造成潛在安全隱患! 類似以上機制,如果異常出現了,我認為可以大大減少debug的時間。