Java自定義異常理解

前言:看了許多博客和書,都對自定異常一筆帶過,總讓人感覺莫名奇妙,一直在問自己一個問題,我們能很好的解決異常就很不錯了,爲什麼還要自己自定義異常,讓自己去自找麻煩呢?後來我才理解自定義異常有自己的妙用。

Java錯誤與異常的基本概念:

1.java中異常均繼承自Throwable,其有兩個重要的直接子類error與exception.

2.java錯誤error,大部分是由虛擬機爆出來的錯誤,是程序無法處理的錯誤,如OutOfMemoryError,當JVM需要更多內存空間而得不到滿足時,就會爆出OutOfMemoryError

3.Exception,異常,其下分類很多,如可查異常與不可查異常,運行時異常與非運行時異常,基本概念一樣,只是說法不同罷了。其有個重要的子類即RuntimeException運行時異常,其它直接子類都歸爲非RuntimeException,如IOException,SQLException等。

       a.非RuntimeException是在代碼書寫時,編譯器給你檢查提示你要進行try catch或throws處理。

       b.RuntimeException,編譯器不會幫你自動檢查,當你運行程序時,虛擬機纔會給你爆出錯誤讓你去處理,這個往往是我們編碼邏輯或不規範導致的

下面我們來看看java異常類結構層次圖:


異常中的try,catch,throw,throws,finally,相信都能很好理解,下面我重點來說自定義異常了。


JAVA自定義異常:

自定義異常幾步驟:

1.自定義一個類,集成自Exception

2.重寫父類Exception所有的公共方法

3.重載構造函數


那爲什麼要自定義異常呢,這就涉及到項目結構中的分層思想了,根據MVC架構,一個項目可大體分爲3個層次,

1.是模型層model,這個往往與數據庫中的表結構相對應,今天內容不涉及該層可忽略。

2.是業務邏輯層Contorler,往往處理的是業務邏輯的,如對數據庫的增刪改查,業務邏輯的判斷等。

3.是界面層view,是與用戶交互的層次,往往只用於刷新顯示界面

這些層次都有自己的使命,view層不能又進行業務邏輯的處理又進行界面顯示刷新的操作,這樣管理維護代碼就清晰多了,那麼隨之問題就來了,但我業務邏輯層做了邏輯判斷之後想要view層根據不同的業務進行ui顯示時又該怎麼做呢?這個就需要我們自定義異常類登場了。我們以簡單密碼校驗爲例:

我們只對密碼進行校驗,當登錄時如果密碼爲123提示登錄成功,否則提示失敗

import java.util.Scanner;

public class Login {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String pw = scan.nextLine();
		if ("123".equals(pw)) {
			System.out.println("登錄成功");
		}else{
			System.out.println("登錄失敗");
		}

	}

}

這個是很直接的寫法,邏輯判斷與界面刷新顯示都在view層去處理了,這種寫法不是我們想要的,等到我們項目變大後你會發現view層做界面顯示又做邏輯處理是多麼的愚蠢。

下面我們用分層思想去實現該功能。

1.我們先自定義異常類 MyException


import java.io.PrintStream;
import java.io.PrintWriter;

@SuppressWarnings("serial")
public class MyException extends Exception{
	/**
	 * 重載構造函數
	 */
	public MyException() {
		super();
	}

	public MyException(String message, Throwable cause,
			boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public MyException(String message, Throwable cause) {
		super(message, cause);
	}

	public MyException(String message) {
		super(message);
	}

	public MyException(Throwable cause) {
		super(cause);
	}

	/**
	 * 重寫父類的方法
	 */
	
	@Override
	public String getMessage() {
		// TODO Auto-generated method stub
		return super.getMessage();
	}
	
	@Override
	public String getLocalizedMessage() {
		// TODO Auto-generated method stub
		return super.getLocalizedMessage();
	}

	@Override
	public synchronized Throwable getCause() {
		// TODO Auto-generated method stub
		return super.getCause();
	}

	@Override
	public synchronized Throwable initCause(Throwable cause) {
		// TODO Auto-generated method stub
		return super.initCause(cause);
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return super.toString();
	}

	@Override
	public void printStackTrace() {
		// TODO Auto-generated method stub
		super.printStackTrace();
	}

	@Override
	public void printStackTrace(PrintStream s) {
		// TODO Auto-generated method stub
		super.printStackTrace(s);
	}

	@Override
	public void printStackTrace(PrintWriter s) {
		// TODO Auto-generated method stub
		super.printStackTrace(s);
	}

	@Override
	public synchronized Throwable fillInStackTrace() {
		// TODO Auto-generated method stub
		return super.fillInStackTrace();
	}

	@Override
	public StackTraceElement[] getStackTrace() {
		// TODO Auto-generated method stub
		return super.getStackTrace();
	}

	@Override
	public void setStackTrace(StackTraceElement[] stackTrace) {
		// TODO Auto-generated method stub
		super.setStackTrace(stackTrace);
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return super.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return super.equals(obj);
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}

	@Override
	protected void finalize() throws Throwable {
		// TODO Auto-generated method stub
		super.finalize();
	}

	

}

然後寫我的業務邏輯層LoginService

public class LoginService {
	//這裏不能講exception try catch ,將它拋出去讓view層去捕獲,再進行處理
	public void vertifyPw(String pw) throws MyException{
		if ("123".equals(pw)) {
			throw new MyException("登錄成功");
		}else{
			throw new MyException("登錄失敗");
		}
	}

}

最後刷新view

import java.util.Scanner;

public class Login {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String pw = scan.nextLine();
		LoginService ls = new LoginService();
		// 這裏調用vertifyPw(),方法進行校驗,根據不同的返回值做打印輸出e.getMessage();
		try {
			ls.vertifyPw(pw);
		} catch (MyException e) {
			System.out.println(e.getMessage());
		}

	}

}

我在註釋中已對關鍵地方做了註解,看代碼應該很容易能理解到自定義異常的好處了吧!


結語:不要嘆氣,你現在走的每一步都是爲你昨天的選擇買單,換句話說,這也叫擔當!








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章