前言:看了许多博客和书,都对自定异常一笔带过,总让人感觉莫名奇妙,一直在问自己一个问题,我们能很好的解决异常就很不错了,为什么还要自己自定义异常,让自己去自找麻烦呢?后来我才理解自定义异常有自己的妙用。
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("登录失败");
}
}
}
下面我们用分层思想去实现该功能。
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("登录失败");
}
}
}
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());
}
}
}
结语:不要叹气,你现在走的每一步都是为你昨天的选择买单,换句话说,这也叫担当!