异常:在程序的运行过程中所发生的不正常的情况,它会中断正在运行的程序
异常处理机制
java中通过异常处理机制为程序提供异常处理的能力,保持程序继续运行而不中断
一,常用的异常处理关键字:
(1)try/catch(把有可能产生异常的代码放到try代码块中,catch代码块负责捕获并处理异常)
会发生的三种情况
【1】正常结束
【2】出现异常=>处理异常=>正常结束
【3】出现异常=>处理异常(发现异常类型不匹配)=>程序中断
这种情况下可以利用多重catch 多声明一些异常类型来确保程序不会匹配不到合适的
不过这种作用不大,因为jdk里面给我们提供了两大类异常类型(运行时异常和检查时异常,下面会详细介绍到的)
(2)try/catch/finally
把有可能产生异常的代码放到try中,catch负责匹配并处理异常,finally块用于进行收尾工作(关闭数据库、关闭文件、释放内存等资源)
不管是否发生异常,finally都执行(*除开一种情况:被jvm提前退出程序)
(3)return (注意下存在return的try/catch/finally执行顺序)
*不论异常与否都是最后才输出return
二,异常的分类
只需要关注Exception就行,Exception根据是否处理分为两种情况。
RuntimeException:运行时异常。不要求程序必须做出处理。是所有运行时异常的父类。
CheckedException:检查时异常。要求程序必须处理,不处理编译不通过
常见的运行时异常
ArithmeticException:数学计算异常。比如除数为0
InputMismatchException:输入不匹配异常
ArrayIndexOutofBoundsException:数组下标越界异常。
NullPointException:空指针异常,对象没有初始化就使用时,jvm会抛出该异常
IllegalArgumentException:非法参数异常。
ClassCastException:强制类型转换异常。
NumberFormatException:数字格式化异常。比如把“abc”格式化成数字。
常见的检查时异常:
ClassNotFoundException:类没有被发现异常。
SQLException:数据库相关异常
IOException:IO操作异常
ParseException:解析错误异常
FileNotFoundException:文件未发现异常
三,声明异常
(1)throws关键字
当一个方法可能存在异常,而此时自身又无法更好的处理,可以交给外界处理。此时用throws声明并抛出异常
public class Test01 { public static int div(int a, int b) throws ArithmeticException{ int r = 0; r = a / b; return r; } public static void main(String[] args) { try { Test01.div(10, 0); } catch (ArithmeticException e) { System.out.println("除数不能为0"); } } }
如果调用处也不知道如何处理异常,可选择继续声明异常,我们把这个过程称为异常上抛(终点是jvm)
public class Test01 { public static int div(int a, int b) throws Exception{ int r = 0; r = a / b; return r; } public static void main(String[] args) throws Exception{ Test01.div(10, 0); } }
(2)声明异常和重载的关系(虽然声明异常是跟在方法名后面,看起来和重载是一体的,但和重载没任何关系)
(3)声明异常和重写的关系
[1]父类方法声明了异常(检测时或运行时),子类可以不声明任何异常
public class Father { //父类声明异常 public void showInfo() throws Exception{ } }
public class Son extends Father{
//子类不需要声明 @Override public void showInfo(){ } }
可以认为:父类方法抛出异常,子类在重写过程中把该异常处理掉了,所以子类方法不用声明异常。
[2] 父类方法声明没有声明任何异常(检测时或运行时),子类也不声明异常或者声明运行时异常
[3] 父类声明了异常(检测时或运行时),子类声明完全一样的异常(或者和第一种情况一样不声明)
四,手动抛出异常
除了系统自动抛出异常外(throws关键字),有些问题需要开发者手动抛出异常。使用关键字throw
public void setGender(String gender) throws Exception{ if(gender.equals("男") || gender.equals("女")) { this.gender = gender; }else { throw new Exception("性别不合法!"); } }
Student stu = new Student();
try {
stu.setGender("xxx");
} catch (Exception e) { System.out.println(e.getMessage()); }
自定义异常
如果开发者需要手动抛出的异常在系统不存在,可以自定义异常。
如果要自定义异常,首先要确定异常类型,如果异常是运行时异常,必须继承RuntimeException或其子类;如果异常是检查时异常,必须继承Exception或其子类。
异常的命名方式,参考系统命名方式,以Exception结尾
public class AgeException extends Exception{ //重写 public AgeException() { super(); } public AgeException(String message) { super(message); } }