java異常體系和業務處理

1、java異常體系java

先看Java異常體系圖:app

全部異常類的父類爲Throwable類,兩個直接子類爲Error和Exception分別表示錯誤和異常。ui

一、Error類this

Error是程序沒法處理的錯誤,它是由JVM產生和拋出的,好比OutOfMemoryError、ThreadDeath等。這些異常發生時,Java虛擬機(JVM)通常會選擇線程終止。編碼

二、Exception類spa

Exception是程序自己能夠處理的異常,這種異常分兩大類運行時異常(Unchecked Exception)和非運行時異常(Checked Exception)。程序中應當儘量去處理這些異常。線程

RuntimeException(Unchecked Exception):便可以編譯經過,通常由程序的邏輯錯誤引發,開發過程當中應儘可能避免。例如:NullPointerException,IndexOutOfBoundsException等。自定義異常通常繼承此類。
3d

RuntimeException之外的異常(checked Exception):編譯器在編譯階段進行處理,程序必須處理此類異常不然沒法經過編譯,如IOException、SQLException等。日誌

2、異常的捕獲和處理code

異常的捕獲經過try、catch、finally三個關鍵字,三個語句塊均不能單獨使用,三者能夠組成 try...catch...finally、try...catch、try...finally三種結構,catch語句能夠有一個或多個,finally語句只能一個

一、普通無異常:

public class TestDemo {
	 public static void main(String[] args) {
	        String result = GetString();
	        System.out.print(result);

	    }
    public static String GetString(){
        try
        {
            System.out.print("GetString():try\n");
            return "GetString()返回值\n";
        }
        catch (Exception e)
        {
            System.out.print("GetString():catch\n");
            return "GetString()返回值";
        }
        finally
        {
            System.out.print("GetString():finally\n");
        }
        //return "這裏是方法底部返回值";
    }
}

  運行結果:

整個執行順序以下:執行順序是try=>finally=>return

二、出現異常調用狀況

public class TestDemo {
	 public static void main(String[] args) {
	        String result = GetString();
	        System.out.print(result);
	    }
    public static String GetString(){
        try
        {
            System.out.print("GetString():try\n");
            int i = 0;
        	int var = 1 / i ;
        	System.out.print("執行GetString():1/i\n");
            return "GetString()try 返回值\n";
        }
        catch (Exception e)
        {
            System.out.print("GetString():catch\n");
            return "GetString()catch 返回值";
        }
        finally
        {
            System.out.print("GetString():finally\n");
        }
        //return "這裏是方法底部返回值";
    }
}

  執行結果:

整個執行順序以下:try=>catch=>finally=>catch return

能夠肯定:

1)不論出不出現異常都會執行finally代碼塊

2)在try模塊中出現異常後,異常代碼後續流程都不會繼續執行

三、try、catch、finally模塊中進行賦值

public class TestDemo {
	 public static void main(String[] args) {
	        String result = GetString();
	        System.out.print(result);
	    }
    public static String GetString(){
    	String var = "";
        try
        {
            var = "try var值";
        	System.out.print("執行GetString():var\n");
            return var;
        }
        catch (Exception e)
        {
            System.out.print("GetString():catch\n");
            return "GetString()catch 返回值";
        }
        finally
        {
        	var = "finally var值";
            System.out.print("GetString():finally\n");
        }
    }
}

  執行結果:

經過執行結果能夠看到,在finally中對var進行賦值,雖然程序執行了finally模塊,可是最終不會影響var的值,var的值仍是在try模塊中賦值內容。

結論:雖然finally方法會被執行可是返回結果不會被改變,也就是finally是在return以後執行的,try模塊會先把返回結果先保存起來,而後無論finally代碼執行了什麼,都不會影響到返回結果,等finally執行完成在返回結果。

3、業務如何定義異常

業務中須要按照必定的規範來定義異常,這樣有利於系統管理業務異常。

經過上面繼承圖能夠看出,全部service都會繼承BaseExcepion,BaseException最終經過RuntimeException來實現。

而在實際的業務中須要準肯定位異常歸屬的服務和具體類型,這樣就能夠在對異常日誌進行監控時有區分的進行不一樣的處理(好比重要的賬務或者渠道服務進行較高優先級的提醒或者自處理)。

因此能夠在BaseException經過系統定義的code,code經過兩個部分來組成:不一樣的service定義的值和同一個service中具體異常類型值。

public class BaseException extends RuntimeException {

    private String code;

    public BusinessException() {
        super();
    }

    public BusinessException(String code, String message) {
        super(message);
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    /**
     * 獲取異常編碼
     * @param sysCode 系統編號枚舉
     * @param exceptionType 異常類型枚舉
     * @param exceptionCode 異常順序碼
     * @return String 異常編碼
     */
    protected static String getExceptionCode(SysCode sysCode, ExceptionType exceptionType, String exceptionCode) {

        if (StringUtil.isEmpty(exceptionCode) || StringUtil.length(exceptionCode) != 4) {
            throw new BusinessException("00000000", "異常編碼不符規範");
        }

        return new StringBuilder(sysCode.getCode()).append(exceptionType.getCode()).append(exceptionCode).toString();
    }

    public BusinessException print(String message) {
        logger.error("BusinessException Code:{};Message:{};OtherMessage:{}", this.code, super.getMessage(), message);
        return this;
    }

  在serviceA中經過調用定義異常類型ORDER_PARAM_NULL,自己ServiceA自帶code:SysCode.SER_A,再和定義的1001進行拼接獲得最終的該異常在整個系統中的異常code。

public class ServiceAException extends BusinessException {
    public static FeeException ORDER_PARAM_NULL = new ServiceAException(getExceptionCode( "1001"),
            "關鍵參數爲空");    
    public static String getExceptionCode(String exceptionCode) {
        return getExceptionCode(SysCode.SER_A/*這裏定義serviceA的系統code值*/,  exceptionCode);
    }
}
相關文章
相關標籤/搜索