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异常类结构层次图:

Java自定义异常理解_第1张图片

异常中的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());
		}

	}

}

我在注释中已对关键地方做了注解,看代码应该很容易能理解到自定义异常的好处了吧!


结语:不要叹气,你现在走的每一步都是为你昨天的选择买单,换句话说,这也叫担当!








你可能感兴趣的:(javase学习讲义)