java
异常模块总结一下。本文主要内容:
java
异常关键字定义
在计算机的世界里,在运行程序时,发生了意料之外的事件,阻止了程序的正常执行,这种情况被称之为异常。
在JDK
中有一套完整异常机制,所有异常都是Throwable
的子类,分为Error
(知名异常)和Exception
(非致命异常)。
Error
是一种特殊的异常,它出现标识着系统发生了不可控制的错误,比如:常见的OutOfMemoryError
(内存溢出),StackOverflowError
栈溢出。
Exception又分为checked(受检查)和unchecked(非受检查)异常。
checked受检查的异常是需要在程序中显示处理的异常,否则编译失败。在开发过程中遇到这种异常的时候,一般是要么处理掉该异常,要么直接往上抛。常见的checked异常有:SQLException
,ClassNotFoundException
等。
SQLException
,这时候最好的方式就是打印出异常错误信息,供开发人员排查问题。UnAuthorizedException
,程序可以跳转至权限申请页面。IndexOutOfBoundsException
、NullPointerException
等,面对此等异常,最好解决办法就是开发人员做好相应的边界值校验,或者捕获对应异常就行处理。try catch finally throws throw
以上关键字的解释
throws:使用在方法签名参数后 ,向调用此方法的地方抛一个异常。
throw:使用在方法里面,由于某某原因,需要往外跑一个异常,或者是针对某种异常进行转换成自定义异常,然后往外抛自定义异常。
try:不能单独使用,只能结合catch,finally一起使用,try代码块起到见识程序执行过程,如果一旦程序中发生异常则直接跳到catch模块中,如果没有异常发生则直接跳到finally模块中(前提是try+catch+finally)。
catch:结合try一起使用,可以加入finally模块,也可以是多个catch组合.如果try模块中发生异常并且catch(异常类型)刚刚是对应的异常或者范围更大的时候,就会进入catch模块。
finally:结合try使用,或者结合try+catch一起使用。finally模块表示必须执行的模块。不管程序是否发生异常,都会执行finally模块。注意:没有进入finally的情况有:程序执行没有进入try模块、进入try模块,但是程序中出现死循环了或者死锁状态、进入try模块,但是执行了System.exit();
public class MyException {
//模板1,方法签名参数后向外抛异常
public void test() throws Exception {
}
//模板2,方法里向外抛异常
public void test1() {
throw new Exception();
}
//模板3,处理程序异常的三部曲try--catch--finally
public void test2() {
try {
//doSomething
} catch (Exception ex) {
} finally {
//最后在处理点事情
}
}
//模板4,发现异常,捕获异常,try--catch
public void test3() {
try {
//doSomething
} catch (Exception ex) {
}
}
//模板 4,发现异常,捕获异常,先捕获范围小的,再捕获范围大的
public void test4() {
try {
//doSomething
} catch (NullPointerException ex) {
}catch (Exception ex){
}
}
//模板 5,发现异常,捕获异常,先捕获范围小的,再捕获范围大的,最后在处理点事情
public void test5() {
try {
//doSomething
} catch (NullPointerException ex) {
}catch (Exception ex){
}finally {
//最后在处理点事情
}
}
//模板6,不管有没有捕获到异常,
public void test6() {
try {
//doSomething
} finally {
//最后在处理点事情
}
}
}
在开发过程中难免会想自定义异常,比如说针对某些业务的操作失败,我们如果用其他异常类可能会有歧义,所以使用自定义的异常来和其他异常的区分,也有的时候是针对系统级的,Pay支付模块的异常可以定义成PayException
。但是怎么定义呢?Throwable
分为Error和Exception,所以如果自定义的异常继承于Error的话行么?因为Error是不可控的,所以通常不会继承与它。通常都是自定义异常继承于Exception或者RuntimeException
。如果希望写一个检查性异常类,则需要继承 Exception 类。如果你想写一个运行时异常类,那么需要继承 RuntimeException
类。
//自定义异常,继承于Exception
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class CustomExceptionDemo {
public static void main(String[] args) {
try {
test(22);
} catch (CustomException e) {
System.out.println("test方法报异常," + e.getLocalizedMessage());
}
}
private static void test(int age) throws CustomException {
if (age == 22) {
throw new CustomException("这是我的自定义异常");
} else {
System.out.println("不是自定义异常");
}
}
}
运行结果:
test方法报异常,这是我的自定义异常
在工作中使用比较多的自定义方式,把上面的自定义进行改造:
//自定义
public class CustomException extends Exception {
//错误码
private String errorCode;
//错误信息
private String errorMsg;
public CustomException(String errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
//省略调 get set toString
}
public class CustomExceptionDemo {
public static void main(String[] args) {
try {
test(2);
} catch (CustomException e) {
System.out.println("test方法报异常,异常信息:" + e);
}
}
private static void test(int age) throws CustomException {
if (age == 2) {
throw new CustomException("300001", "这是我的自定义异常");
} else {
System.out.println("不是自定义异常");
}
}
}
运行输出结果:
test方法报异常,异常信息:CustomException{errorCode='300001', errorMsg='这是我的自定义异常'}
注意:异常堆栈信息,不是有多少就打多少,这方面也要悠着点,过多地打印错误日志也是会拖累系统的,能表达清楚就OK了。
异常就说到这里,期待下一期的异常面试题。